Я смотрю на проблему с медленными запросами и не могу понять, почему использование LIMIT 20 для этого запроса замедляет его в 100 раз.
Запрос выглядит следующим образом:
SELECT DISTINCT e.eventid,e.clock,e.ns,e.objectid,e.acknowledged,er1.r_eventid
FROM events e JOIN event_recovery er1 ON er1.eventid=e.eventid
WHERE e.source='0' AND e.object='0' AND e.objectid='115779'
AND e.eventid<='65535859' AND e.value='1'
ORDER BY e.eventid
LIMIT 20;
ОБЪЯСНЕНИЕ:
Без ограничения 20:
EXPLAIN SELECT DISTINCT e.eventid... ORDER BY e.eventid;
+------+-------------+-------+--------+---------------------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+
| 1 | SIMPLE | e | ref | PRIMARY,events_1,events_2 | events_1 | 16 | const,const,const | 15792 | Using index condition; Using where; Using temporary; Using filesort |
| 1 | SIMPLE | er1 | eq_ref | PRIMARY | PRIMARY | 8 | zabbix_server.e.eventid | 1 | |
+------+-------------+-------+--------+---------------------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+
(4256 строк в наборе (0,050 с c) при выполнении без EXPLAIN)
с LIMIT 20:
EXPLAIN SELECT DISTINCT e.eventid... ORDER BY e.eventid LIMIT 20;
+------+-------------+-------+--------+---------------------------+---------+---------+-------------------------+---------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------------------+---------+---------+-------------------------+---------+------------------------------+
| 1 | SIMPLE | e | range | PRIMARY,events_1,events_2 | PRIMARY | 8 | NULL | 2969589 | Using where; Using temporary |
| 1 | SIMPLE | er1 | eq_ref | PRIMARY | PRIMARY | 8 | zabbix_server.e.eventid | 1 | |
+------+-------------+-------+--------+---------------------------+---------+---------+-------------------------+---------+------------------------------+
(20 строк в наборе (9,269 se c) при выполнении без EXPLAIN)
Почему он не использует ключи для LIMIT 20?
Я использую MariaDB 10.3.11 в Debian 9
EDIT: Принудительно использование INDEX делает это быстрым, но почему оптимизатор MySQL не понимает этого?
EXPLAIN SELECT DISTINCT e.eventid,e.clock,e.ns,e.objectid,e.acknowledged,er1.r_eventid FROM events e USE INDEX (events_1) JOIN event_recovery er1 ON er1.eventid=e.eventid WHERE e.source='0' AND e.object='0' AND e.objectid='115779' AND e.eventid<='65535859' AND e.value='1' ORDER BY e.eventid LIMIT 20;
+------+-------------+-------+--------+---------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+
| 1 | SIMPLE | e | ref | events_1 | events_1 | 16 | const,const,const | 15820 | Using index condition; Using where; Using temporary; Using filesort |
| 1 | SIMPLE | er1 | eq_ref | PRIMARY | PRIMARY | 8 | zabbix_server.e.eventid | 1 | |
+------+-------------+-------+--------+---------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+