Mam tabelę CustPassMaster
z 16 kolumnami, z których jedna jest CustNum varchar(8)
, i utworzyłem indeks IX_dbo_CustPassMaster_CustNum
. Kiedy uruchamiam moje SELECT
oświadczenie:
SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678'
Całkowicie ignoruje indeks. To mnie myli, ponieważ mam inną tabelę CustDataMaster
ze znacznie większą liczbą kolumn (55), z których jedna to CustNum varchar(8)
. Utworzyłem indeks dla tej kolumny ( IX_dbo_CustDataMaster_CustNum
) w tej tabeli i używam praktycznie tego samego zapytania:
SELECT * FROM dbo.CustDataMaster WHERE CustNum = '12345678'
I korzysta z indeksu, który utworzyłem.
Czy kryje się za tym jakieś uzasadnienie? Dlaczego miałby korzystać z indeksu z CustDataMaster
, ale nie z tego CustPassMaster
? Czy wynika to z niskiej liczby kolumn?
Pierwsze zapytanie zwraca 66 wierszy. Po drugie zwracany jest 1 wiersz.
Ponadto dodatkowa uwaga: CustPassMaster
ma 4991 rekordów i CustDataMaster
5376 rekordów. Czy może to być powodem ignorowania indeksu? CustPassMaster
ma również zduplikowane rekordy, które również mają te same CustNum
wartości. Czy to kolejny czynnik?
Opieram to twierdzenie na faktycznych wynikach planu wykonania obu zapytań.
Oto DDL dla CustPassMaster
(tego z nieużywanym indeksem):
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]
I DDL dla CustDataMaster
(pominąłem wiele niepotrzebnych pól):
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]
Nie mam indeksu klastrowego w żadnej z tych tabel, tylko jeden indeks nieklastrowany.
Zignoruj fakt, że typy danych nie są całkowicie zgodne z typem przechowywanych danych. Te pola stanowią kopię zapasową bazy danych IBM AS / 400 DB2 i są to zgodne typy danych dla niej. (Muszę być w stanie wykonać zapytanie do tej zapasowej bazy danych dokładnie tymi samymi zapytaniami i uzyskać dokładnie takie same wyniki).
Te dane są wykorzystywane tylko do SELECT
wyciągów. Nie wykonuję na nim żadnych instrukcji INSERT
/ UPDATE
/ DELETE
, z wyjątkiem sytuacji, gdy aplikacja do kopiowania kopiuje dane z AS / 400.