2016-03-07 4 views
0

Здравствуйте, так как я обновление с MySQL 5.5 на Percona 5,7Mysql 5,7 не использовать индекс

Этот запрос:

SELECT COUNT(a.alarm_id) AS `count`, MAX(a.alarm_id) AS `max_alarm_id`, `a`.`priority` 
    FROM `alarm` AS `a` 
    WHERE (a.maintenance_suppress = '0') 
    AND (a.deleted_at = '0000-00-00 00:00:00') 
    AND (a.object_id = '6') 
    GROUP BY `a`.`priority` 

WONT индексы используют, как ожидалось больше.

Это объясняет для запроса:

+----+-------------+-------+------------+------+---------------------------------------------------------------------+-----------+---------+-------------------+------+----------+--------------------------------------------------------+ 
| id | select_type | table | partitions | type | possible_keys              | key  | key_len | ref    | rows | filtered | Extra             | 
+----+-------------+-------+------------+------+---------------------------------------------------------------------+-----------+---------+-------------------+------+----------+--------------------------------------------------------+ 
| 1 | SIMPLE  | a  | NULL  | ref | maintenance_suppress,alarm_count,deleted_at,object_id,alarm_count_b | object_id | 10  | const,const,const | 1 | 100.00 | Using index condition; Using temporary; Using filesort | 
+----+-------------+-------+------------+------+---------------------------------------------------------------------+-----------+---------+-------------------+------+----------+--------------------------------------------------------+ 

И это мое индексирование:

Keyname     Type Unique Packed Column      Cardinality Collation Null 
PRIMARY     BTREE Yes  No  alarm_id     1156170  A   No 
quited_by    BTREE No  No  acknowledged_by     78  A   Yes 
deleted_by    BTREE No  No  deleted_by      9  A   Yes 
device_id    BTREE No  No  component_id     820  A   Yes 
message_status_create BTREE No  No  message_status_create    2  A   No 
leaved_at    BTREE No  No  leaved_at     597481  A   No 
               message_status_leaved  527117  A   No 
acknowledged_at   BTREE No  No  acknowledged_at    139029  A   No 
               message_status_acknowledged 176719  A   No 
maintenance_suppress BTREE No  No  maintenance_suppress    1  A   No 
ticket_id    BTREE No  No  ticket_id       1  A   Yes 
alarm_count    BTREE No  No  priority       5  A   No 
               specified_class     8  A   No 
               maintenance_suppress    8  A   No 
               deleted_at     27340  A   No 
               object_id      21310  A   No 
deleted_at    BTREE No  No  deleted_at     29538  A   No 
specified_class   BTREE No  No  specified_class     2  A   No 
created_at    BTREE No  No  created_at     876796  A   No 
object_id    BTREE No  No  object_id      192  A   No 
               deleted_at     10261  A   No 
               maintenance_suppress   56175  A   No 
alarm_count_b   BTREE No  No  priority       6  A   No 
               maintenance_suppress    9  A   No 
               deleted_at     31421  A   No 
               object_id      46226  A   No 

Если я заставить индекс это собирается быть медленнее:

mysql> SELECT COUNT(a.alarm_id) AS `count`, MAX(a.alarm_id) AS `max_alarm_id`, `a`.`priority` 
    ->  FROM `alarm` AS `a` 
    ->  WHERE (a.maintenance_suppress = '0') 
    ->  AND (a.deleted_at = '0000-00-00 00:00:00') 
    ->  AND (a.object_id = '68') 
    ->  GROUP BY `a`.`priority`; 
+-------+--------------+----------+ 
| count | max_alarm_id | priority | 
+-------+--------------+----------+ 
|  8 |  1278404 |  2 | 
+-------+--------------+----------+ 
1 row in set (0.01 sec) 

mysql> SELECT COUNT(a.alarm_id) AS `count`, MAX(a.alarm_id) AS `max_alarm_id`, `a`.`priority` 
    ->  FROM `alarm` AS `a` FORCE INDEX (alarm_count_b) 
    ->  WHERE (a.maintenance_suppress = '0') 
    ->  AND (a.deleted_at = '0000-00-00 00:00:00') 
    ->  AND (a.object_id = '68') 
    ->  GROUP BY `a`.`priority`; 
+-------+--------------+----------+ 
| count | max_alarm_id | priority | 
+-------+--------------+----------+ 
|  8 |  1278404 |  2 | 
+-------+--------------+----------+ 
1 row in set (0.67 sec) 

Кто-нибудь знает, что не так с моими индексами?

SQL скрипку играть Arround: http://sqlfiddle.com/#!9/23949/1

+0

В вашем запросе используются индексы в соответствии с объяснением. Какие индексы вы ожидали использовать (alarm_count_b возможно?)?С замедлением происходит значительное замедление? – Shadow

+0

Да, я бы ожидал alarm_count_b, и он медленно замедляется. В процентах 30 – GreenRover

+0

Вы пробовали использовать индексный указатель (индекс силы) в своем запросе? – Shadow

ответ

1

Подозреваемый причина обновления, возможно, имели эффект в том, что она проделала ANALYZE TABLE при выполнении обновления, поэтому в настоящее время выбора индекса из обновленных статистических данных.

Индекс, который он использует сейчас, кажется более логичным для столбцов, которые у вас есть в предложениях WHERE. Все 3 столбца в индексе используются в предложении WHERE. Индекс alarm_count_b имеет столбец, используемый для GROUP BY в начале индекса, но это действительно полезно только после того, как записи были исключены предложением WHERE.

Однако попробуйте добавить приоритет в качестве дополнительного столбца в конце индекса object_id.

0

Вы не сказали, что это 5.5 сделал против 5.7. В любом случае у вас нет оптимального индекса, поэтому я отвечу на эту проблему.

WHERE (a.maintenance_suppress = '0') 
AND (a.deleted_at = '0000-00-00 00:00:00') 
AND (a.object_id = '6') 
GROUP BY `a`.`priority` 

просит INDEX(maintenance_suppress, deleted_at, object_id, priority) в любом порядке, за исключением того, что priority должен быть последний. Предложите добавить priority в INDEX object_id.

Как правило, начинают с = условия, а затем перейти к один состоянии в диапазоне WHERE. Если WHERE завершен, то один диапазон может быть полем GROUP BY или ORDER BY.

More discussion of index building.

Другое примечание. Предполагая, что вы используете InnoDB, alarm_id будет частью этого индекса, тем самым делая его «покрывающим». Это дает дополнительный импульс. alarm_count_b также покрывает, но столбцы не расположены в оптимальном порядке, следовательно, это низкая производительность.

Не видя других запросов, я не могу судить о других ваших индексах, кроме как сказать 14 индексов «много».

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

  • Нет связанных вопросов^_^