J'ai une table, CustPassMaster
avec 16 colonnes, dont une CustNum varchar(8)
, et j'ai créé un index IX_dbo_CustPassMaster_CustNum
. Lorsque je lance ma SELECT
déclaration:
SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678'
Il ignore complètement l'index. Cela m'embrouille car j'ai un autre tableau CustDataMaster
avec beaucoup plus de colonnes (55), dont l'une est CustNum varchar(8)
. J'ai créé un index sur cette colonne ( IX_dbo_CustDataMaster_CustNum
) dans cette table, et utilise pratiquement la même requête:
SELECT * FROM dbo.CustDataMaster WHERE CustNum = '12345678'
Et il utilise l'index que j'ai créé.
Y a-t-il un raisonnement spécifique derrière cela? Pourquoi utiliserait-il l'index de CustDataMaster
, mais pas celui de CustPassMaster
? Est-ce dû au faible nombre de colonnes?
La première requête renvoie 66 lignes. Pour le second, 1 ligne est retournée.
Remarque supplémentaire: CustPassMaster
contient 4991 enregistrements et CustDataMaster
5376 enregistrements. Serait-ce le raisonnement derrière l'ignorance de l'index? CustPassMaster
contient également des enregistrements en double qui ont également les mêmes CustNum
valeurs. Est-ce un autre facteur?
Je fonde cette revendication sur les résultats réels du plan d'exécution des deux requêtes.
Voici le DDL pour CustPassMaster
(celui avec l'index inutilisé):
CREATE TABLE dbo.CustPassMaster(
[CustNum] [varchar](8) NOT NULL,
[Username] [char](15) NOT NULL,
[Password] [char](15) NOT NULL,
/* more columns here */
[VBTerminator] [varchar](1) NOT NULL
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_dbo_CustPassMaster_CustNum] ON dbo.CustPassMaster
(
[CustNum] ASC
) WITH (PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, SORT_IN_TEMPDB = OFF
, DROP_EXISTING = OFF
, ONLINE = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Et le DDL pour CustDataMaster
(j'ai omis beaucoup de champs non pertinents):
CREATE TABLE dbo.CustDataMaster(
[CustNum] [varchar](8) NOT NULL,
/* more columns here */
[VBTerminator] [varchar](1) NOT NULL
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_dbo_CustDataMaster_CustNum] ON dbo.CustDataMaster
(
[CustNum] ASC
)WITH (PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, SORT_IN_TEMPDB = OFF
, DROP_EXISTING = OFF
, ONLINE = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Je n'ai pas d'index cluster sur aucune de ces tables, un seul index non cluster.
Ignorez le fait que les types de données ne correspondent pas entièrement au type de données stockées. Ces champs sont une sauvegarde d'une base de données IBM AS / 400 DB2, et ce sont les types de données compatibles pour celle-ci. (Je dois pouvoir interroger cette base de données de sauvegarde avec exactement les mêmes requêtes et obtenir exactement les mêmes résultats.)
Ces données ne sont utilisées que pour les SELECT
déclarations. Je ne fais aucune instruction INSERT
/ UPDATE
/ DELETE
dessus, sauf lorsque l'application de sauvegarde copie des données de l'AS / 400.