重複索引 - 相同的鍵,一個包含 INCLUDE 列,刪除哪一個?
我有 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
列。