Что заставляет оптимизатор прекратить использование индекса? - PullRequest
0 голосов
/ 23 апреля 2020

Предположим, у меня есть таблица A с первичным ключом

PRIMARY KEY(c1,c2)

, а количество элементов c1 очень мало, а c2 очень велико

При выполнении следующих запросов

select *
from A
where (c1, c2) in (('001', 'aaa'))


select *
from A
where c1 = '001'and c2 = 'aaa'

оптимизатор использует индекс.

Однако для следующих случаев

Случай 1:

select *
from A
where (c1, c2) in (('001', 'aaa'), ('002', 'bbb'), ('003', 'ccc'))

Случай 2:

select *
from A
where (c1 = '001'and c2 = 'aaa') or
      (c1 = '002'and c2 = 'bbb') or
      (c1 = '003'and c2 = 'ccc')

оптимизатор прекращает использовать индекс для случая 1, но все еще использует для случая 2.

Что заставляет оптимизатор прекратить использование индекса для дела 1?

*MySQL Версия: 5.6.10

1 Ответ

3 голосов
/ 23 апреля 2020

Хотя эти выражения семантически эквивалентны, в MySQL добавлена ​​только Оптимизация диапазона выражений конструктора строк , которая фактически может выполнять их таким же образом, в MySQL 5.7.3 (выделено мной):

Оптимизатор сейчас может применять метод доступа к сканированию диапазона для запросов этой формы:

SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' ));

Ранее для использования сканирования диапазона необходимо было записать запрос в виде:

SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' )
  OR ( col_1 = 'c' AND col_2 = 'd' );

Чтобы оптимизатор использовал сканирование диапазона, запросы должны удовлетворять следующим условиям:

  • Используются только предикаты IN (), а не NOT IN ().
  • В левой части предиката IN () конструктор строки содержит только ссылки на столбцы.
  • В правой части предиката IN () конструкторы строк содержат только константы времени выполнения, которые являются литералами или локальными ссылками на столбцы, которые связаны с константами во время выполнения.
  • В правой части IN () предикат т. е. существует более одного конструктора строки .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...