Некластеризованные индексы будут частично покрывать запрос select

#sql #indexing #non-clustered-index

#sql #индексирование #некластеризованный индекс

Вопрос:

У меня есть некластеризованные индексы, созданные на моем сервере базы данных SQL с Include ключевым словом.

Пожалуйста, найдите мой некластеризованный индекс, созданный для FACTORS таблицы.

 CREATE NONCLUSTERED INDEX [FACTORS_BKEY_PNO_IDX] ON [dbo].[FACTORS]
(
                [BATCH_KEY] ASC,
                [PART_NO] ASC
)
INCLUDE([FACTOR_NAME],[FACTOR_VALUE],[FACTOR_NAME_ETL],[INDUSTRY],[PROGRAM_ID],[PROGRAM_NAME]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
  

если у SELECT меня есть запрос, подобный приведенному ниже, будут ли мои индексы FACTORS_BKEY_PNO_IDX покрывать мой запрос select. (я имею в виду, поможет ли этот индекс моему приведенному ниже запросу select быстрее извлекать записи или мне нужно создать другие индексы с точным совпадением INCLUDE полей).

 select 
BATCH_KEY , 
FACTOR_NAME , 
FACTOR_VALUE , 
INDUSTRY  
PART_NO , 
CREATED_TS , 
FACTOR_NAME_ETL , 
PROGRAM_ID , 
PROGRAM_NAME 
from 
FACTORS  
where BATCH_KEY and  PART_NO
order by 
PART_NO, FACTOR_NAME, FACTOR_VALUE
  

Ответ №1:

Поскольку некластеризованный индекс не включает все поля в вашем запросе SELECT (например, у него их нет Industry ), он не является покрывающим индексом. К сожалению, потребуется получить эти дополнительные данные из другого места, например, вернувшись к исходной таблице.

Индексы могут помочь двумя основными способами

  • покрывающий индекс, содержащий все столбцы, необходимые для запроса, где он может уменьшить объем считываемых данных
  • предварительная сортировка данных, позволяющая выполнить поиск по индексу

Быстрее всего, когда происходят оба из них, например, он отсортирован соответствующим образом и является покрывающим индексом. В вашем примере похоже, что основные поля индекса соответствуют, но это не покрывающий индекс.

Предварительная сортировка все равно может помочь, даже если это не охватывающий индекс, например, он использует индекс для определения, какие строки нужно вернуть в таблицу, чтобы получить остальные данные. Он использует индекс так же, как вы бы использовали индекс в книге — например, вы используете индекс, чтобы найти соответствующие страницы в книге, затем перейдите и прочитайте каждую страницу, чтобы получить необходимую информацию. В этих случаях меньший индекс (например, только для batch_key и part_no, никаких других полей) будет функционировать так же, как и более широкий индекс, который у вас есть. Действительно, меньший индекс был бы незначительно лучше, поскольку в нем меньше данных для чтения (2 столбца против 8): потому что ему все равно нужно возвращаться к таблице, чтобы получить данные; он также может получить и другие столбцы оттуда.

Однако, если индекс указывает, что для этого слишком много строк, часто механизм SQL просто прочитает всю таблицу сразу, как если бы там уже не было индекса.

Брент Озар делает действительно хорошее видео об этом под названием «Как думать как движок SQL Server«, учитывая, что вы используете dbo. Я предполагаю, что вы используете SQL Server. Я настоятельно рекомендую посмотреть его, поскольку я много узнал об индексах и т. Д. Из него, И у вас, похоже, хороший базовый уровень знаний, чтобы также многое получить.

(PS — я предполагаю, что where BATCH_KEY and PART_NO это просто опечатка).