Почему MySQL не использует какой-либо из этих возможных ключей?
У меня есть следующий запрос:
SELECT t.id
FROM account_transaction t
JOIN transaction_code tc ON t.transaction_code_id = tc.id
JOIN account a ON t.account_number = a.account_number
GROUP BY tc.id
Когда я делаю EXPLAIN
, первая строка показывает, среди прочего, следующее:
table: t
type: ALL
possible_keys: account_id,transaction_code_id,account_transaction_transaction_code_id,account_transaction_account_number
key: NULL
rows: 465663
Почему ключ NULL?
Ответы
Ответ 1
Возможно, это связано с тем, что статистика разбита или потому, что она знает, что у вас всегда есть соотношение 1:1 между двумя таблицами.
Вы можете заставить индекс использоваться в запросе и посмотреть, ускорит ли это действие. Если это так, попробуйте запустить ANALYZE TABLE, чтобы убедиться, что статистика обновлена.
Указывая USE INDEX (index_list), вы можете указать MySQL использовать только один из названных индексов для поиска строк в таблице. Альтернативный синтаксис IGNORE INDEX (index_list) можно использовать, чтобы сообщить MySQL не использовать какой-либо определенный индекс или индексы. Эти подсказки полезны, если EXPLAIN показывает, что MySQL использует неверный индекс из списка возможных индексов.
Вы также можете использовать FORCE INDEX, который действует как USE INDEX (index_list), но с добавлением, что сканирование таблицы считается очень дорогостоящим. Другими словами, сканирование таблицы используется только в том случае, если нет способа использовать один из указанных индексов для поиска строк в таблице.
В каждом подсказке требуются имена индексов, а не имена столбцов. Имя ПЕРВИЧНОГО КЛЮЧА ПЕРВИЧНО. Чтобы увидеть имена индексов для таблицы, используйте SHOW INDEX.
Из http://dev.mysql.com/doc/refman/5.1/en/index-hints.html
Ответ 2
Другой проблемой, с которой вы можете столкнуться, является неправильное совпадение типов данных. Например, если ваш столбец является строковым типом данных (CHAR, для ex), и ваш запрос не цитирует число, тогда MySQL не будет использовать индекс.
SELECT * FROM tbl WHERE col = 12345; # No index
SELECT * FROM tbl WHERE col = '12345'; # Index
Источник: только что вошел в эту же проблему сегодня и усердно изучил MySQL 5.1.:)
Изменить: дополнительную информацию для подтверждения:
mysql> desc das_table \G
*************************** 1. row ***************************
Field: das_column
Type: varchar(32)
Null: NO
Key: PRI
Default:
Extra:
*************************** 2. row ***************************
[SNIP!]
mysql> explain select * from das_table where das_column = 189017 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: das_column
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 874282
Extra: Using where
1 row in set (0.00 sec)
mysql> explain select * from das_table where das_column = '189017' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: das_column
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 34
ref: const
rows: 1
Extra:
1 row in set (0.00 sec)
Ответ 3
Указатель для group by
(= неявный order by
)
...
GROUP BY tc.id
Группа с помощью неявного сортировки на tc.id.
tc.id не указан в качестве возможного ключа.
но t.transaction_id -.
Измените код на
SELECT t.id
FROM account_transaction t
JOIN transaction_code tc ON t.transaction_code_id = tc.id
JOIN account a ON t.account_number = a.account_number
GROUP BY t.transaction_code_id
Это приведет к представлению потенциального индекса transaction_code_id
.
Индексы для объединений
Если соединения (почти) полностью присоединяются к трем таблицам, нет необходимости использовать индекс, поэтому MySQL этого не делает.
Другие причины не использовать индекс
Если большая часть рассматриваемых строк (40% IIRC) заполняется с одинаковым значением. MySQL не использует индекс. (потому что не использовать индекс быстрее)