Использование ORDER BY ... LIMIT 20; делает запрос очень медленным - PullRequest
0 голосов
/ 15 апреля 2020

Я смотрю на проблему с медленными запросами и не могу понять, почему использование 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 |                                                                     |
+------+-------------+-------+--------+---------------+----------+---------+-------------------------+-------+---------------------------------------------------------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...