Sql-Server

重複索引 - 相同的鍵,一個包含 INCLUDE 列,刪除哪一個?

  • November 1, 2018

我有 2 個索引具有相同的鍵,但一個也有 INCLUDE 列。我可以放棄哪一個?

它們是相同的,除了IndexInclude有 6 個 INCLUDE 列。

兩者都有一些讀取(IndexNoInclude 具有更高的搜尋次數)。

我相信IndexInclude將滿足使用IndexNoInclude的任何內容,對嗎?因為鑰匙完全一樣。

感謝您提前提供的所有幫助。

sp_Blitz 的輸出。抱歉格式不好

詳細資訊:db_schema.table.index(indexid) 
定義:[Property] ColumnName {datatype maxbytes} Secret Columns Fillfactor Usage Stats Op Stats Size

**IndexINCLUDE** [1 KEY] EXECUTION_TIME {datetime 8} [6 INCLUDES] 
讀取:101,913(101,913 尋軌) 寫入:2,381,661,369 
0 個單例查找;225 次掃描/搜尋;0 次刪除;0 次更新;263,358,683 行;5.4GB

**IndexNoInclude** [1 KEY] EXECUTION_TIME {datetime 8}
讀取:1,181,595(1,181,595 次搜尋) 寫入:2,380,483,678 
0 個單例查找;15 次掃描/搜尋;0 次刪除;0 次更新;263,358,683 行;2.9GB

在使用IndexInclude查看查詢計劃後,我確認他們並沒有真正使用 6 Included 列(主要是 SELECT),所以我禁用了IndexInclude

到目前為止一切順利,我繼續監控

這些是我用來查找它們的查詢(來自 SQLSkills 和 Kendra) https://www.sqlskills.com/blogs/jonathan/finding-what-queries-in-the-plan-cache-use-a-specific-索引/ https://littlekendra.com/2017/01/24/how-to-find-queries-using-an-index-and-queries-using-index-hints/

我將兩者結合併修改以獲得我需要的內容(查看實際文本/查詢、執行計數、讀取/寫入、上次執行時間)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
DECLARE @IndexName AS NVARCHAR(128) = 'IndexInclude';

-- Make sure the name passed is appropriately quoted 
IF (LEFT(@IndexName, 1) <> '[' AND RIGHT(@IndexName, 1) <> ']') SET @IndexName = QUOTENAME(@IndexName); 
--Handle the case where the left or right was quoted manually but not the opposite side 
IF LEFT(@IndexName, 1) <> '[' SET @IndexName = '['+@IndexName; 
IF RIGHT(@IndexName, 1) <> ']' SET @IndexName = @IndexName + ']';

-- Dig into the plan cache and find all plans using this index 
;WITH XMLNAMESPACES 
  (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')    
SELECT 
stmt.value('(@StatementText)[1]', 'varchar(max)') AS SQL_Text, 
--obj.value('(@Database)[1]', 'varchar(128)') AS DatabaseName, obj.value('(@Schema)[1]', 'varchar(128)') AS SchemaName, obj.value('(@Table)[1]', 'varchar(128)') AS TableName, 
--obj.value('(@Index)[1]', 'varchar(128)') AS IndexName, obj.value('(@IndexKind)[1]', 'varchar(128)') AS IndexKind, 
--cp.plan_handle, 
qp.query_plan,
cp.usecounts AS execution_count
,
   querystats.execution_count,
   querystats.total_logical_reads,
   querystats.total_logical_writes,
   querystats.creation_time,
   querystats.last_execution_time
FROM sys.dm_exec_cached_plans AS cp 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qp 
CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS batch(stmt) 
CROSS APPLY stmt.nodes('.//IndexScan/Object[@Index=sql:variable("@IndexName")]') AS idx(obj) 
--added by Jerry to get the time
INNER JOIN     sys.dm_exec_query_stats querystats WITH (NOLOCK) ON  querystats.plan_handle = cp.plan_handle
ORDER BY querystats.last_execution_time DESC
OPTION(MAXDOP 1, RECOMPILE);

我相信IndexInclude將滿足使用IndexNoInclude的任何內容,對嗎?因為鑰匙完全一樣

他們是一樣的嗎?也許我誤讀了輸出,但看起來IndexNoInclude肯定有一個額外的鍵列:[ID] NUMERIC

您應該查看您的查詢以查看INCLUDE實際引用/使用了 6 列中的哪一列。您可能會通過“合併”這兩個索引而僥倖逃脫,這樣剩餘的索引就具有兩個鍵列以及 1 到 6 個INCLUDE列。

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