Добавление определенного индекса в таблицу SQL Server для повышения производительности - PullRequest
0 голосов
/ 12 апреля 2019

У меня медленный запрос к таблице.

SELECT (some columns)
FROM Table

Эта таблица имеет первичный индекс ID (целое число, идентификатор (1,1)), который является единственным индексом в этой таблице.

В запросе есть предложение WHERE:

WHERE Field05 <> 1 
  AND (Field01 LIKE '%something%' OR Field02 LIKE '%something%' OR 
       Field03 LIKE'%something%' OR Field04 LIKE'%something%')
  • Field05 является bit, not null
  • Field01 является NVarchar(255)
  • Field02 - это NVarchar(255)
  • Field03 - это Nchar(11)
  • Field04 - это Varchar(50)

План выполнения показывает «Сканирование кластеризованного индекса», что приводит к медленному выполнению.

Я пытался добавить индексы:

CREATE NONCLUSTERED INDEX IX_Aziende_RagSoc ON dbo.Aziende (Field01);
CREATE NONCLUSTERED INDEX IX_Aziende_Nome ON dbo.Aziende (Field02);
CREATE NONCLUSTERED INDEX IX_Aziende_PIVA ON dbo.Aziende (Field03);
CREATE NONCLUSTERED INDEX IX_Aziende_CodFisc ON dbo.Aziende (Field04);
CREATE NONCLUSTERED INDEX IX_Aziende_Eliminata ON dbo.Aziende (Field05);

Те же характеристики, и снова план выполнения показывает «Сканирование кластеризованного индекса» Я удалил эти 5 индексов и добавил только ОДИН индекс:

CREATE NONCLUSTERED INDEX IX_Aziende_Ricerca
ON Aziende (Field05)
INCLUDE (Field01, Field02, Field03, Field04)

Те же характеристики, но в этой ситуации план выполнения меняется.

Более сложный, но всегда медленный.

Я удалил этот индекс и добавил другой индекс:

CREATE NONCLUSTERED INDEX IX_Aziende_Ricerca
ON Aziende (Field05,Field01,Field02,Field03,Field04)

Те же характеристики, в этой ситуации план выполнения остается таким же, как и в предыдущей ситуации.

Выполнение всегда медленное.

У меня нет других идей ... кто-то может помочь?

Ответы [ 3 ]

0 голосов
/ 12 апреля 2019

Просто позвоните с несколькими комментариями. SQL Server имеет тенденцию к сканированию таблиц, даже если индекс присутствует, если он не считает, что поле «Поиск» имеет мощность менее 1%. Учитывая это, в индексе битового поля никогда не будет никакого значения. (мощность 50%!)

Один из вариантов, который вы можете рассмотреть, - это создание фильтрованного индекса (WHERE Field05 = 0). Затем вы можете включить другие поля в этот индекс. Обратите внимание, что это поможет вам, только если вы не выбираете другие столбцы из таблицы.

Можете ли вы проверить, какая доля ваших данных имеет Field5 = 0? - Если это мало (например, менее 10%), тогда может помочь отфильтрованный индекс.

Я не вижу способа, чтобы вы могли избежать какого-либо сканирования - лучшее, что вы можете получить, это, вероятно, сканирование индекса.

Другой вариант (по сути то же самое!) - создать индексированное представление с привязкой к схеме со всеми необходимыми столбцами и жестко закодированным в поле фильтром field5 = 0.

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

Итак, подведем итог - если вы можете гарантировать, что будет выбрано небольшое подмножество таблицы, столбцы И field5 = 0 представляет меньшинство ваших строк в таблице, тогда может быть полезен отфильтрованный индекс с включениями.

EG

СОЗДАТЬ НЕКЛАСТЕРНЫЙ ИНДЕКС ix ON dbo.Aziende (ID) ВКЛЮЧИТЬ (Field01, Field02, Field03, Field04, [другие столбцы, используемые для выбора]) WHERE (field5 = 0)

Удачи!

0 голосов
/ 13 апреля 2019

После долгой борьбы я забыл идею добавить индекс.С индексом ничего не меняется.

Я изменил код C #, который строит запрос, и теперь я пытаюсь понять значение параметра «что-то», полученного от функции.Если это тип 1, то я строю WHERE на Field01. Если это тип 2, то я строю WHERE на Field02. Если это тип 3, то я строю WHERE на Field03. Если он имеет тип 4, тоЯ строю WHERE на Field04

Таким образом, время выполнения становится 1/4 от предыдущего.Курстомеры довольны.

0 голосов
/ 12 апреля 2019

Это слишком долго для комментария.

Во-первых, вы должны использовать Field05 = 0 вместо Field05 <> 1.Равенство легче читается и лучше для оптимизатора.Это не будет иметь значения в этом конкретном случае, если только у вас нет кластеризованного индекса, начинающегося с Field05 или если почти все значения 1 (то есть 0 очень избирательно).

Во-вторых, как правило, вы можете оптимизировать сопоставление строковых шаблонов только с помощью полнотекстового индекса.Это, в свою очередь, имеет другие ограничения, такие как поиск слов или префиксов (но не начиная с подстановочных знаков).

Единственное исключение, если «что-то» является константой.В этом случае можно добавить постоянные вычисляемые столбцы с индексами, чтобы определить, присутствует ли значение в этих столбцах.Однако я предполагаю, что «что-то» не является постоянным.

Это оставляет вас с полнотекстовыми индексами или с пересмотром вашей модели данных.Возможно, вы храните вещи в строках - например, списки тегов - которые действительно должны быть в отдельной таблице.

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