Почему извлечь последнюю часть (LIMIT и OFFSET) строк из MYSQL намного медленнее, чем извлекать все остальные части? - PullRequest
1 голос
/ 07 мая 2020

Мне нужно извлечь довольно большой кусок данных из базы данных (MYSQL MariaDB), поэтому я решил взять его небольшими порциями (ограничение = 1000 строк). Всего мне нужно извлечь ~ 9228 строк (звучит немного, но время выборки достигает 100-120 секунд, когда я пытаюсь получить все 9228 строк одновременно с одним запросом).

Когда я получаю первые 8 блоков данных (По 1000 строк), все хорошо ~ 0,4 секунды на запрос. Но когда я пытаюсь извлечь последние 228 строк, все идет очень медленно - 80 секунд, если я использую LIMIT 1000 OFFSET 9000, или 50 секунд, когда я использую точное количество строк для LIMIT LIMIT 228 OFFSET 9000. Но запрос, который используется для получения общего количества строк, занимает 30 секунд, поэтому два запроса снова составляют 80 секунд.

Мой sql запрос на получение данных выглядит следующим образом:

SELECT events.eventid, functions.triggerid FROM events
INNER JOIN functions ON  events.objectid = functions.triggerid
WHERE
events.name LIKE 'DISCONNECT MSK-AP%'
OR events.name LIKE 'AP MSK-AP%'    # '%MSK-AP%'  is much slower than OR
AND events.value = 1
AND events.clock >= '1588280400' 
AND events.clock <= '1590958799'
GROUP BY events.eventid
ORDER BY events.eventid DESC
LIMIT 1000 OFFSET 0;  # SO OFFSET COULD BE 0, 1000, 2000,  ... 8000, 9000

Мой sql запрос на получение общего количества строк (он занимает 30 секунд медленно!) Выглядит следующим образом:

SELECT COUNT(distinct(events.eventid)) FROM events
INNER JOIN functions ON  events.objectid = functions.triggerid
WHERE
events.name LIKE 'DISCONNECT MSK-AP%'
OR events.name LIKE 'AP MSK-AP%'
AND events.value = 1
AND events.clock >= '1588280400' 
AND events.clock <= '1590958799';

Версия моей базы данных :

протокол_версии 10 slave_type_conversions
версия 5.5.60-MariaDB версия_комментария сервера MariaDB версия_компилированной_машины x86_64 версия_компиляции_os Linux

Почему последний запрос на получение последнего фрагмента выполняется так медленно по сравнению с другим и что я могу сделать, чтобы решить эту проблему? Может ли временная таблица базы данных помочь в этом случае?

Почему я не уверен, что ответ на вопрос подходит для моего случая: Почему MYSQL более высокое смещение LIMIT замедляет выполнение запроса ?

Поскольку проблемы не коррелируют с РАЗМЕРОМ СМЕЩЕНИЯ, например:

LIMIT 100 OFFSET 9100; - 0,25 секунды, НО LIMIT 100 OFFSET 9200; - 114 секунд!

Итак, проблема возникает, когда смещение + предел близко или больше, чем общее количество строк (9228)!

1 Ответ

1 голос
/ 25 мая 2020

OFFSET отстой.

Лучше «вспомнить, где вы остановились».

Обсуждение: http://mysql.rjweb.org/doc.php/pagination

Почему медленнее, чем чтение всего?

При использовании OFFSET запрос сначала подсчитывает количество строк, заданных OFFSET, а затем выдает количество строк, заданных LIMIT. Итак, он становится все медленнее и медленнее. Окончательное смещение занимает примерно столько же времени, сколько и чтение всей таблицы.

...