Почему MySQL не использует ни один из этих возможных ключей? - PullRequest
23 голосов
/ 19 апреля 2011

У меня следующий запрос:

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?

Ответы [ 3 ]

48 голосов
/ 29 апреля 2011

Другая проблема, с которой вы можете столкнуться, - несоответствие типов данных.Например, если ваш столбец является строковым типом данных (CHAR, например), а ваш запрос не заключает в кавычки число, MySQL не будет использовать индекс.та же самая проблема сегодня, и изучил трудный путь на 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)
17 голосов
/ 19 апреля 2011

Это может быть из-за того, что статистика не работает или потому, что она знает, что между двумя таблицами всегда есть соотношение 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

8 голосов
/ 19 апреля 2011

Индекс для 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 не использует индекс. (потому что не использовать индекс быстрее)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...