Sql-Server

在哪裡表現受到打擊

  • December 10, 2021

我收到了一個 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 JOINUF_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查詢中的子句仍然存在)?

引用自:https://dba.stackexchange.com/questions/303777