Почему MySQL не использует индексы с составной WHERE IN? - PullRequest
3 голосов
/ 06 марта 2012

Я пытаюсь получить несколько записей по составному индексу из таблицы, имеющей PRIMARY KEY (a, b)

SELECT * FROM table WHERE (a, b) IN ((1,2), (2,4), (1,3))

Проблема в том, что MySQL не использует индекс, даже если я FORCE INDEX (PRIMARY).
EXPLAIN SELECT показывает нулевые возможные_ключи.

Почему нет возможных_ключей?

Как лучше всего получить несколько строк по составному ключу:

  • с использованием ИЛИ
  • с использованием UNION ALL
  • с использованием WHERE () IN ((), ())

P.S. Результат равен по результату

SELECT * FROM table WHERE (a = 1 AND b = 2) OR (a = 2 AND b = 4) OR (a = 1 AND b = 3)

Спасибо

Ответы [ 3 ]

2 голосов
/ 07 марта 2012

Если запрос выбирает только поля из индекса (или если в таблице нет других полей) по составному WHERE ... IN, будет использоваться индекс:

SELECT a,b FROM `table` WHERE (a, b) IN ((1,2), (2,4), (1,3))

В противном случае он не будет использоваться. Обходной путь должен использовать производный запрос:

SELECT t.* FROM (SELECT a, b FROM `table` WHERE (a, b) IN ((1,2), (2,4), (1,3))) AS o INNER JOIN `table` AS t ON (t.a = o.a AND t.b = o.b)

ОБЪЯСНИТЬ ВЫБОР:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    2   
1   PRIMARY t   eq_ref  PRIMARY PRIMARY 2   o.a,o.b 1   
2   DERIVED table   index   NULL    PRIMARY 2   NULL    6   Using where; Using index
0 голосов
/ 06 марта 2012

Попробуйте создать объединенный индекс для столбцов a, b.

Индекс не должен быть первичным ключом, и он все еще может помочь.

Больше информации о вашей проблемездесь: http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html

0 голосов
/ 06 марта 2012

В сильном желании индексировать определенный столбец, вы рассматривали вопрос о наличии нового столбца: a_b, который в основном CONCAT(a, '-', b), и просто сравните его (WHERE a_b = {$id1}-{$id2})?

И вы можете иметь толькоодин первичный столбец на таблицу.Вы не можете "индексировать основной" как a, так и b

...