在哪裡表現受到打擊
我收到了一個 SQL 查詢,詢問為什麼它執行不佳。他們聲稱該查詢與擁有類似數據集的其他客戶沒有任何性能問題,並將性能問題歸咎於我們正在執行 SQL 2016 的事實……
SELECT DISTINCT t.ID_, t.EXECUTION_ID_, t.PROC_INST_ID_, <...snip...> t.TENANT_ID_, e.business_key_, wd.def_key FROM ACT_RU_TASK t LEFT JOIN ACT_RU_IDENTITYLINK link ON (t.id_=link.task_id_ AND link.type_='candidate') LEFT JOIN ACT_RU_EXECUTION e ON e.proc_inst_id_ = t.proc_inst_id_ AND e.parent_id_ IS NULL LEFT JOIN UF_WORKFLOW_INSTANCE wi ON e.proc_inst_id_=wi.process_instance LEFT JOIN UF_WORKFLOW_DEFINITION wd ON wd.id=wi.workflow_definition_fk WHERE link.group_id_ IN ( <...12 strings here...> ) ORDER BY t.CREATE_TIME_ DESC
查詢按以下方式執行,統計資訊如下
SQL Server Execution Times: CPU time = 3813 ms, elapsed time = 4148 ms.
如果我們刪除“WHERE … IN”子句
(3809 rows affected) SQL Server Execution Times: CPU time = 250 ms, elapsed time = 388 ms.
WHERE … IN 子句會對性能造成如此大的影響是否正常?估計的和實際的執行計劃也有很大差距。
正如彼得所指出的,您
LEFT JOIN
要UF_WORKFLOW_INSTANCE.process_instance
使用的謂詞ACT_RU_EXECUTION.proc_inst_id_
顯示了執行計劃中發生的隱式轉換:$$ mydatabase $$.$$ dbo $$.$$ ACT_RU_EXECUTION $$.$$ PROC_INST_ID_ $$作為$$ e $$.$$ PROC_INST_ID_ $$= CONVERT_IMPLICIT(nvarchar(64) ,$$ mydatabase $$.$$ dbo $$.$$ uf_workflow_instance $$.$$ process_instance $$作為$$ wi $$.$$ process_instance $$,0).
這表明您的基數估計問題的潛在原因。其他客戶端可能在其執行計劃中也存在相同的根本問題,但具有不同的數據分佈,因此不會導致相同的基數估計問題。
如果您首先具體化
UF_WORKFLOW_INSTANCE
到臨時表並在將process_instance
欄位NVARCHAR(64)
插入臨時表時將其轉換為,然後加入到該臨時表中,性能是否再次變得更好(即使IN
查詢中的子句仍然存在)?