#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
это просто опечатка).