SQL Server: почему SELECT для столбца без учета регистра выполняется быстрее, чем для столбца с учетом регистра?

Я использую SQL Server 2016 Express и приложение Java с драйвером JDBC версии 4.2.

Моя база данных имеет сопоставление Latin1_General_CI_AS (без учета регистра). В моей таблице есть столбец типа VARCHAR(128) NOT NULL. В этом столбце есть уникальный индекс.

Мой тестовый сценарий выглядит следующим образом:

После вставки 150000 строк длиной 48 символов я делаю 200 выборок случайно выбранных существующих строк. Я измеряю общее время выполнения всех запросов.

Затем я удаляю индекс, изменяю таблицу, чтобы изменить сопоставление столбцов на Latin1_General_CS_AS (с учетом регистра) и снова создаю уникальный индекс.

Тогда 200 выборок занимают больше времени.

В обоих случаях (CI и CS) планы выполнения просты и идентичны (поиск по индексу).

Время выполнения запроса зависит не только от чувствительности к регистру. При сопоставлении CS он растет быстрее, если строки имеют одинаковые префиксы. Вот мои результаты (время выполнения в секундах):

+----+---------+------------------+-------------------+-------------------+
|    + RND(48) + CONST(3)+RND(45) + CONST(10)+RND(38) + CONST(20)+RND(28) +
+----+---------+------------------+-------------------+-------------------+
| CI +       6 +                6 +                 7 +                 9 +
| CS +      10 +               20 +                45 +                78 +
+----+---------+------------------+-------------------+-------------------+

Чем длиннее идентичный префикс случайных строк, тем больше времени занимают запросы с учетом регистра.

  1. Почему поиск в столбце без учета регистра выполняется быстрее, чем в столбце с учетом регистра?
  2. В чем причина одинакового поведения префикса?

person zuserus    schedule 11.09.2017    source источник
comment
Что означает search by using the index? Сканирование индекса выполняется медленно, а поиск по индексу выполняется быстро. Публикация запросов и планов выполнения   -  person Panagiotis Kanavos    schedule 15.05.2018
comment
Кстати, вы указали новую сортировку при воссоздании индекса? Что означает it grows faster if the strings have identical prefixes? Вы не можете использовать индекс для поиска в середине поля, например, с помощью LIKE %whatever``. Только запросы, соответствующие префиксу, могут использовать индекс, т.е. LIKE 'whatever%'. Использует ли какой-либо запрос индекс?   -  person Panagiotis Kanavos    schedule 15.05.2018


Ответы (1)


Причина в том, что ваша установка SQL (я предполагаю) была выполнена с сопоставлением CI. Это означает, что ваши базы данных tempdb и master используют CI, как и ваша собственная база данных. Таким образом, даже если вы изменили свой символьный столбец на CS, когда он используется в базе данных tempdb для операций сортировки/слияния, которые выполняются в контексте CI. Чтобы получить точное сравнение, вам нужно изменить параметры сортировки установки на CS или провести эти сравнения параллельно на разных экземплярах SQL — один с использованием CS, а другой — с CI.

person Lee James    schedule 15.05.2018
comment
tempdb не используется, если нет индексов или данных так много, что серверу приходится хранить частичные результаты. Это может произойти, если индекс не используется. В OP упоминаются префиксы, что заставляет меня задаться вопросом, использует ли запрос такие условия, как LIKE '%something' - person Panagiotis Kanavos; 15.05.2018