Sql-Server

缺失索引創建建議

  • April 3, 2019

我一直在使用 sp_blitzindex,它非常有幫助(感謝 Brent Ozar 和團隊)。我對我的數據庫執行了這個過程,下面是一個屬於 Indexaphobia 組的表的發現:

sp_blitzindex 輸出

下面是基礎表的定義:

CREATE TABLE [dbo].[table_name](
   [L] [int] IDENTITY(1,1) NOT NULL,
   [R] [varchar](15) NOT NULL,
   [A] [int] NOT NULL,
   [VAR32_01] [varchar](32) NULL,
   [VAR32_02] [varchar](32) NULL,
   [VAR32_03] [varchar](32) NULL,
   [VAR32_04] [varchar](32) NULL,
   [VAR32_05] [varchar](32) NULL,
   [VAR32_06] [varchar](32) NULL,
   [VAR32_07] [varchar](32) NULL,
   [VAR32_08] [varchar](32) NULL,
   [VAR32_09] [varchar](32) NULL,
   [VAR32_10] [varchar](32) NULL,
   [VAR32_11] [varchar](32) NULL,
   [VAR32_12] [varchar](32) NULL,
   [VAR32_13] [varchar](32) NULL,
   [VAR32_14] [varchar](32) NULL,
   [VAR32_15] [varchar](32) NULL,
   [VAR32_16] [varchar](32) NULL,
   [VAR32_17] [varchar](32) NULL,
   [VAR32_18] [varchar](32) NULL,
   [VAR32_19] [varchar](32) NULL,
   [VAR32_20] [varchar](32) NULL,
   [VAR32_21] [varchar](32) NULL,
   [VAR32_22] [varchar](32) NULL,
   [VAR32_23] [varchar](32) NULL,
   [VAR32_24] [varchar](32) NULL,
   [VAR32_25] [varchar](32) NULL,
   [VAR32_26] [varchar](32) NULL,
   [VAR32_27] [varchar](32) NULL,
   [VAR32_28] [varchar](32) NULL,
   [VAR32_29] [varchar](32) NULL,
   [VAR32_30] [varchar](32) NULL,
   [VAR32_31] [varchar](32) NULL,
   [VAR32_32] [varchar](32) NULL,
   [VAR32_33] [varchar](32) NULL,
   [VAR32_34] [varchar](32) NULL,
   [VAR32_35] [varchar](32) NULL,
   [VAR32_36] [varchar](32) NULL,
   [VAR32_37] [varchar](32) NULL,
   [VAR32_38] [varchar](32) NULL,
   [VAR32_39] [varchar](32) NULL,
   [VAR32_40] [varchar](32) NULL,
   [VAR32_41] [varchar](32) NULL,
   [VAR32_42] [varchar](32) NULL,
   [VAR32_43] [varchar](32) NULL,
   [VAR32_44] [varchar](32) NULL,
   [VAR32_45] [varchar](32) NULL,
   [VAR32_46] [varchar](32) NULL,
   [VAR32_47] [varchar](32) NULL,
   [VAR32_48] [varchar](32) NULL,
   [VAR32_49] [varchar](32) NULL,
   [VAR32_50] [varchar](32) NULL,
   [VAR32_51] [varchar](32) NULL,
   [VAR32_52] [varchar](32) NULL,
   [VAR32_53] [varchar](32) NULL,
   [VAR32_54] [varchar](32) NULL,
   [VAR32_55] [varchar](32) NULL,
   [VAR32_56] [varchar](32) NULL,
   [VAR32_57] [varchar](32) NULL,
   [VAR32_58] [varchar](32) NULL,
   [VAR32_59] [varchar](32) NULL,
   [VAR32_60] [varchar](32) NULL,
   [VAR32_61] [varchar](32) NULL,
   [VAR32_62] [varchar](32) NULL,
   [VAR32_63] [varchar](32) NULL,
   [VAR32_64] [varchar](32) NULL,
   [VAR64_01] [varchar](64) NULL,
   [VAR64_02] [varchar](64) NULL,
   [VAR64_03] [varchar](64) NULL,
   [VAR64_04] [varchar](64) NULL,
   [VAR64_05] [varchar](64) NULL,
   [VAR64_06] [varchar](64) NULL,
   [VAR64_07] [varchar](64) NULL,
   [VAR64_08] [varchar](64) NULL,
   [VAR64_09] [varchar](64) NULL,
   [VAR64_10] [varchar](64) NULL,
   [VAR64_11] [varchar](64) NULL,
   [VAR64_12] [varchar](64) NULL,
   [VAR64_13] [varchar](64) NULL,
   [VAR64_14] [varchar](64) NULL,
   [VAR64_15] [varchar](64) NULL,
   [VAR64_16] [varchar](64) NULL,
   [VAR64_17] [varchar](64) NULL,
   [VAR64_18] [varchar](64) NULL,
   [VAR64_19] [varchar](64) NULL,
   [VAR64_20] [varchar](64) NULL,
   [VAR64_21] [varchar](64) NULL,
   [VAR64_22] [varchar](64) NULL,
   [VAR64_23] [varchar](64) NULL,
   [VAR64_24] [varchar](64) NULL,
   [VAR64_25] [varchar](64) NULL,
   [VAR64_26] [varchar](64) NULL,
   [VAR64_27] [varchar](64) NULL,
   [VAR64_28] [varchar](64) NULL,
   [VAR64_29] [varchar](64) NULL,
   [VAR64_30] [varchar](64) NULL,
   [VAR64_31] [varchar](64) NULL,
   [VAR64_32] [varchar](64) NULL,
   [VAR128_01] [varchar](128) NULL,
   [VAR128_02] [varchar](128) NULL,
   [VAR128_03] [varchar](128) NULL,
   [VAR128_04] [varchar](128) NULL,
   [VAR128_05] [varchar](128) NULL,
   [VAR128_06] [varchar](128) NULL,
   [VAR128_07] [varchar](128) NULL,
   [VAR128_08] [varchar](128) NULL,
   [VAR128_09] [varchar](128) NULL,
   [VAR128_10] [varchar](128) NULL,
   [VAR128_11] [varchar](128) NULL,
   [VAR128_12] [varchar](128) NULL,
   [VAR128_13] [varchar](128) NULL,
   [VAR128_14] [varchar](128) NULL,
   [VAR128_15] [varchar](128) NULL,
   [VAR128_16] [varchar](128) NULL,
   [VAR256_01] [varchar](256) NULL,
   [VAR256_02] [varchar](256) NULL,
   [VAR256_03] [varchar](256) NULL,
   [VAR256_04] [varchar](256) NULL,
   [VAR256_05] [varchar](256) NULL,
   [VAR256_06] [varchar](256) NULL,
   [VAR256_07] [varchar](256) NULL,
   [VAR256_08] [varchar](256) NULL,
   [VAR512_01] [varchar](512) NULL,
   [VAR512_02] [varchar](512) NULL,
   [VAR512_03] [varchar](512) NULL,
   [VAR512_04] [varchar](512) NULL,
   [VAR1024_01] [varchar](1024) NULL,
   [VAR1024_02] [varchar](1024) NULL,
   [E] [varchar](20) NULL,
   [M] [varchar](40) NULL,
   [E] [varchar](50) NULL,
   [N] [varchar](40) NULL,
   [TN] [int] NULL,
   [T] [numeric](1, 0) NULL,
   [D] [numeric](1, 0) NULL,
CONSTRAINT [XPKtable_name] PRIMARY KEY NONCLUSTERED 
(
   [L] ASC,
   [R] ASC
)

根據這些缺少的索引詳細資訊,我計劃創建具有以下定義的索引:

create nonclustered index table_name_incl(A,VAR32_02) include(L,R,E,T,D,VAR32_10,VAR32_18,VAR32_19,VAR32_20,VAR64_11,VAR64_02,VAR32_42,VAR32_39,VAR32_38,VAR32_35,VAR32_39,VAR32_24,VAR32_25,VAR32_27)

我根據所有 6 個缺失索引統計資訊中這些列的出現次數得出了上述列。

從表定義中可以看出,這是一個堆,並且在該表上沒有聚集索引。

感謝您對此的指導或任何幫助。

Version: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) Sep 7 2018 01:37:51 Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 (Build 9600: ) (Hypervisor)

來自評論

聚集索引會帶來許多約束,如空值、重複等,而非聚集索引不會給供應商帶來任何風險,而且他們很容易就達成一致。

這不是真的,聚集索引不允許重複、NULL 甚至重複 NULL,除非它們被聲明為 UNIQUE。

這些插入都會成功:

DROP TABLE IF EXISTS dbo.t;

CREATE TABLE dbo.t ( id INT NULL );

CREATE CLUSTERED INDEX c ON dbo.t ( id );


INSERT dbo.t ( id )
VALUES ( 1 );
INSERT dbo.t ( id )
VALUES ( 1 );
INSERT dbo.t ( id )
VALUES ( 1 );

INSERT dbo.t ( id )
VALUES ( NULL );
INSERT dbo.t ( id )
VALUES ( NULL );
INSERT dbo.t ( id )
VALUES ( NULL );

SELECT *
FROM   dbo.t AS t;

這些插入將在第一個唯一值之後失敗:

DROP TABLE IF EXISTS dbo.t;

CREATE TABLE dbo.t ( id INT NULL );

CREATE UNIQUE CLUSTERED INDEX c ON dbo.t ( id );


INSERT dbo.t ( id )
VALUES ( 1 );
INSERT dbo.t ( id )
VALUES ( 1 );
INSERT dbo.t ( id )
VALUES ( 1 );

INSERT dbo.t ( id )
VALUES ( NULL );
INSERT dbo.t ( id )
VALUES ( NULL );
INSERT dbo.t ( id )
VALUES ( NULL );

SELECT *
FROM   dbo.t AS t;

您的建議起到了作用,我在測試環境中的 A 列上創建了聚集索引,到目前為止根本沒有抱怨缺少索引,只是補充說測試中也缺少索引抱怨。在與供應商確認後,我們將很快將此更改推廣到生產。非常感謝。

👍👍👍

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