Индексирование 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).