Индексирование SQL for Между запросом только с одним совпадением?

У нас есть таблица с более чем двумя миллионами строк, где все запросы против нее будут выполняться с помощью Column1 и Column2. Кроме того, будет только один возможный результат. Например...

Col1     Col2
1        5
6        10
11       15

select * from table1 where 8 between Col1 and Col2

В настоящее время у меня есть уникальный кластерный индекс на Col1 и Col2. До сих пор мне не удалось выяснить, как дальше настраивать запрос и индексы, чтобы минимизировать обрабатываемые строки. План выполнения в настоящее время сообщает о стоимости почти 0,5 и 113 тыс. Строк, обрабатываемых при определении правильного ответа.

Какие опции я могу игнорировать?

В соответствии с запросом, некоторые детали из текущего плана выполнения:

Operation
 Clustered Index Seek
Predicate
 CONVERT_IMPLICIT(bigint,[@2],0)<=[Col2]
Seek Predicate
 Seek Keys[1]: End: Col1 <= Scalar Operator(CONVERT_IMPLICIT(bigint,[@1],0))

Ответ 1

Я думаю, что нашел ответ. Я должен был начать с создания уникального кластерного индекса на Col1, а затем создать уникальный Unclustered Index на Col2. Затем запрос должен был быть обновлен для принудительного поиска по каждому индексу.

select * from table1 where Col1 = 
    (select max(Col1) from table1 where Col1 <= 8)
and Col2 = 
    (select min(Col2) from table1 where Col2 >= 8)

В плане выполнения теперь сообщается стоимость 0.0098 и 1 строка.

Ответ 2

Являются ли диапазоны всегда неперекрывающимися? Вы говорите, что всегда есть только одно совпадение. Если они есть, вы можете записать его как:

SELECT * FROM table1 
   WHERE 8 <= Col2 
   ORDER BY Col2 ASC
   LIMIT 1

Это даст вам строку с наименьшим значением Col2, которая выше 8 - это интересующий вас диапазон. Индекс будет нужен только на Col2, а стоимость должна быть небольшой.

Поскольку вы не упомянули используемую СУБД, LIMIT 1 следует заменить тем, что использует ваша БД, чтобы получить первые результаты N.

Вам нужно будет проверить Col1 <= your_value в коде, чтобы убедиться, что значение, которое вы ищете, действительно находится в диапазоне.

Ответ 3

select * from table1 where Col1 <= 8 and Col2 >= 8

Может быть, "между" с двумя столбцами вызывает проблему.

Кроме того, у вас должен быть только один составной индекс для обоих столбцов (Col1, Col2).