Sql-Server
如何找出目前查詢計劃中的“Key Lookups”?
我正在查詢以列出目前正在執行的請求中存在的鍵查找,我基本上想解決這個問題,看看我是否可以從執行計劃中消除這些鍵查找。
要獲取這些鍵查找,我使用以下查詢:
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%'
這個查詢我面臨的問題是它返回 any
key 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