Sql-Server

如何找出目前查詢計劃中的“Key Lookups”?

  • May 4, 2022

我正在查詢以列出目前正在執行的請求中存在的鍵查找,我基本上想解決這個問題,看看我是否可以從執行計劃中消除這些鍵查找

要獲取這些鍵查找,我使用以下查詢:

SELECT 
   er.session_id,
   er.blocking_session_id,
   er.start_time,
   er.status,
   dbName = DB_NAME(er.database_id),
   er.wait_type,
   er.wait_time,
   er.last_wait_type,
   er.granted_query_memory,
   er.reads,
   er.logical_reads,
   er.writes,
   er.row_count,
   er.total_elapsed_time,
   er.cpu_time,
   er.open_transaction_count,
   er.open_transaction_count,
   s.text,
   qp.query_plan,
   logDate = CONVERT(DATETIME,GETDATE()),
   logTime = CONVERT(DATETIME,GETDATE())
FROM sys.dm_exec_requests er 
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) s
CROSS APPLY sys.dm_exec_query_plan(er.plan_handle) qp
WHERe er.session_id <> @@SPID
 and CONVERT(VARCHAR(MAX), qp.query_plan) LIKE '%IndexScan Lookup%'

這個查詢我面臨的問題是它返回 anykey lookup而不管它的成本

在此處輸入圖像描述

我想過濾那些,我只想看到昂貴的鍵查找。

如何過濾我的查詢以僅顯示昂貴的查找操作?

這不是一個好主意。

從我這拿走。很久以前,我sp_BlitzCache對找到的帶有 Key Lookups 的計劃進行了檢查,然後將該運營商的成本與計劃的總成本進行了比較。如果它> 50%或其他東西,我會將其標記為昂貴的。

我不會再這樣做了。

問題是,成本在現實世界中具有絕對零開爾文的意義。隨著查詢計劃中存在操作員時間,這一點變得更加明顯。

修復每個 Key Lookup 不太可能解決您最糟糕的性能問題,並且很可能最終會得到很多非常寬的索引。

您最好的選擇是根據平均 CPU 消耗或已知會導致特定業務問題的查詢來調整查詢,並調整這些計劃中實際速度較慢的部分。

Key Lookups 並不表示性能問題,就像計劃或運營商的高成本不表示一樣。您需要獲取實際的執行計劃以找出表現不佳的內容。

您可以使用 XQuery 過濾 XML 計劃。例如:

WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')

..........
..........

WHERE er.session_id <> @@SPID
 AND qp.query_plan.exist('
 ShowPlanXML/BatchSequence/Batch/Statements/*
   [
    xs:decimal(@StatementSubTreeCost) div 2
    >
    (descendant::RelOp[IndexScan[@Lookup="1"]][1]/@EstimatedTotalSubtreeCost)
   ]
') = 1;

它的作用如下:

  • 它從計劃的頂部開始,下降到表示任何名稱ShowPlanXML/BatchSequence/Batch/Statements/*的節點。*

  • 它採用StatementSubTreeCost屬性的值,轉換為decimal然後除以2(您可以選擇另一個計算)。

  • 然後獲取原始節點的所有後代節點,RelOp稱為

    • 檢查他們是否有一個名為的子節點,該節點具有一個具有值IndexScan的屬性Lookup``1
    • EstimatedTotalSubtreeCost屬性
  • 然後將第一個值與所有這些值進行比較。

  • 如果有匹配則返回1

db<>小提琴

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