2012-06-15 8 views
2

У меня есть таблица из более чем 9 миллионов строк. У меня есть запрос SELECT, для которого я использую индекс. Вот запрос:MySQL Несоответствия в использовании индекса по тому же запросу

SELECT `username`,`id` 
FROM `04c1Tg0M` 
WHERE `id` > 9259466 
AND `tried` = 0 
LIMIT 1; 

Этот запрос выполняется очень быстро (0,00 сек). Вот объясните для этого запроса:

+----+-------------+----------+-------+-----------------+---------+---------+------+-------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+----------+-------+-----------------+---------+---------+------+-------+-------------+ 
| 1 | SIMPLE  | 04c1Tg0M | range | PRIMARY,triedex | PRIMARY | 4  | NULL | 10822 | Using where | 
+----+-------------+----------+-------+-----------------+---------+---------+------+-------+-------------+ 

Теперь вот тот же запрос, за исключением того, что я собираюсь изменить идентификатор 6259466:

SELECT `username`,`id` 
FROM `04c1Tg0M` 
WHERE `id` > 5986551 
AND `tried` = 0 
LIMIT 1; 

Этот запрос занял 4,78 секунд. Это проблема. Вот объяснение для этого запроса:

+----+-------------+----------+------+-----------------+---------+---------+-------+---------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+----------+------+-----------------+---------+---------+-------+---------+-------------+ 
| 1 | SIMPLE  | 04c1Tg0M | ref | PRIMARY,triedex | triedex | 2  | const | 9275107 | Using where | 
+----+-------------+----------+------+-----------------+---------+---------+-------+---------+-------------+ 

Что происходит здесь и как его исправить? Вот мои показатели:

+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| 04c1Tg0M |   0 | PRIMARY |   1 | id   | A   |  9275093 |  NULL | NULL |  | BTREE  |   | 
| 04c1Tg0M |   1 | pdex  |   1 | username | A   |  9275093 |  NULL | NULL |  | BTREE  |   | 
| 04c1Tg0M |   1 | pdex  |   2 | id   | A   |  9275093 |  NULL | NULL |  | BTREE  |   | 
| 04c1Tg0M |   1 | pdex  |   3 | tried  | A   |  9275093 |  NULL | NULL | YES | BTREE  |   | 
| 04c1Tg0M |   1 | triedex |   1 | tried  | A   |   0 |  NULL | NULL | YES | BTREE  |   | 
| 04c1Tg0M |   1 | triedex |   2 | id   | A   |  9275093 |  NULL | NULL |  | BTREE  |   | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

И вот моя структура таблицы:

| 04c1Tg0M | CREATE TABLE `04c1Tg0M` (
`id` int(20) NOT NULL AUTO_INCREMENT, 
`username` varchar(50) NOT NULL, 
`tried` tinyint(1) DEFAULT '0', 
PRIMARY KEY (`id`), 
KEY `pdex` (`username`,`id`,`tried`), 
KEY `triedex` (`tried`,`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=9275108 DEFAULT CHARSET=utf8 | 
+0

Вы запустили эти запросы сразу после другого? – Dancrumb

+0

в течение нескольких секунд друг от друга – xendi

+2

Вы поняли, что изучаете 3М строк больше (с учетом того, что идентификаторы являются коррелятивными), чем в первом запросе? В результате получается только одна строка, но вы изучаете много строк больше. – Ander2

ответ

1

Первый SQL возвращает 10822 строк, в то время как второй один возвращает 9275107 строк!

Использование индекса первичного ключа «id» во втором запросе не так полезно, потому что вам все равно нужно выполнить полное сканирование таблицы.

Оптимизатор, основанный на затратах MySQL, считает, что в случае второго запроса лучше использовать индекс в «проверке».

Если вам нужно выполнить полное сканирование таблицы, вам лучше не использовать индекс, поскольку индекс представляет собой дополнительные чтения дисков.

Вы можете использовать «индекс использования» или «индекс силы» в своем запросе, чтобы намекнуть оптимизатору, использовать ли индекс.

Также обновляйте статистику, анализируя таблицу периодически, чтобы оптимизатор на основе затрат работал правильно.

+0

, заставляющий индексировать или индексировать намеки, безусловно, сделает работу –

Смежные вопросы