Порядок индекса столбцов и сканирование вместо поиска - PullRequest
0 голосов
/ 17 марта 2020

Пожалуйста, рассмотрите Customer таблицу в Northwind База данных:

Я добавляю индекс по 3 столбцам:

CREATE NONCLUSTERED INDEX [idx_1] ON [dbo].[Customers]
    ([CompanyName] ASC, [City] ASC, [Country] 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]

, и я проверил эти запросы:

1) SELECT CompanyName,city,country FROM [Northwind].[dbo].[Customers] where CompanyName='a' and city='b' and country='c'

2) SELECT CompanyName,city,country FROM [Northwind].[dbo].[Customers] where country='c' and CompanyName='a' and city='b'

3) SELECT CompanyName,city,country FROM [Northwind].[dbo].[Customers] where CompanyName='a' and country='c'

4) SELECT CompanyName,city,country FROM [Northwind].[dbo].[Customers] where CompanyName='a' and city='b'

все вышеперечисленные запросы используют Index Seek.

Существуют ли эти предикаты Верно ?

A) Если в моем индексе есть N столбцов, то все перестановки этих N столбцов с для равенства их значений используется Index Seek, поэтому порядок столбцов в Index не имеет значения, когда все столбцы участвуют в предложении Where.

B) Если в моем индексе есть N столбцы (например: Col1, Col2, Col3,...) then all these combinations in Где clause use Index Seek`:

B-1) Col1, Col2,
B-2) Col1, Col2, Col3
B-3) Col1, Col3, Col4
B-4) Col1, Col4, Col7

Поэтому Col1 важно использовать Index Seek.

Пожалуйста, рассмотрите этот запрос:

5) SELECT CompanyName,city,country, PostalCode FROM [Northwind].[dbo].[Customers] where CompanyName='a' and city='b' and country='c'

C) Я добавил PostalCode в список выбора и почему Index Seek конвертируется в Index Scan? Почему Seek не конвертируется в Seek + Key Lookup?

1 Ответ

1 голос
/ 17 марта 2020

1) Порядок столбцов имеет значение, потому что ключ индекса создается с использованием указанного порядка столбцов. Таким образом, поиск по индексу (а не сканирование) может быть эффективно выполнен, только если в ваш предикат включен столбец CompanyName (как и во всех ваших пунктах WHERE). Порядок, в котором столбцы перечислены в предикате, не имеет значения - оптимизатор запросов выяснит, указаны ли необходимые столбцы для выполнения поиска.

2) Опять же, необходимо включить Col1 поскольку это первый столбец, указанный для индекса и, следовательно, формирующий начало ключа индекса.

3) Добавление PostalCode означает, что индекс больше не охватывает все столбцы, необходимые для предоставления sh запрос. Затем оптимизатор запросов должен оценить, является ли поиск индекса или сканирование индекса более эффективным. Это будет зависеть от ряда факторов, но важным будет то, сколько строк, которые он оценивает, будет возвращено предикатом, и, следовательно, сколько (дорогих) ключевых операций поиска ему придется выполнить относительно затрат на сканирование таблицы (кластеризовано). индекс). Он четко решил, что в этом случае сканирование кластерного индекса более эффективно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...