всю выдачу, а сразу обрубает
Отсутствие сортировки либо сортировка по индексу, в зависимости от того, насколько быстро у вас найдётся нужное число записей.
В таком запросе select * from table limit 10 Вы итак получаете сразу 10 записей и только их. Другие не будут подниматься с диска. В таком запросе select * from table order by x limit 10 и есть индекс по x, то Pg снова прочитает только 10 строк и несколько страниц в индексе. Если индекса нет, то магии не будет, конечно, прочитается вся таблица, посортируется и возьмётся первые 10. В других СУБД думаю так же.
Памяти на такую сортировку (последний случай) уйдёт гораздо меньше, чем на полный quicksort, который будет без limit, потому что сперва честно отсортируются 10 записей, затем БД пройдёт скользящим окном из этих 10 записей, вписывая новые строки только если они должны занять место до уже существующих строк.
О, интересное замечание. Т.е. там, видимо, heap (структура данных). В него кладут и извлекают быстро за log от числа записей в heap. Так?
За log2(число записей) можно найти в отсортированном массиве строку, в которую надо вставить следующую запись из неотсортированных данных (при этом, большая часть строк попадёт в конец массива и будет просто отброшена), сами данные строк, видимо, действительно в heap-е размещаются, в итоге. В итоге, сложность по сравнениям получается O(N*log2(m)), где N - общее число строк, а m = limit + offset, если m << N, это будет быстрее, чем делать честную сортировку всех данных, у которой сложность O(N*log2(N)). Я не читал исходники, если что, просто это очевидный путь к ускорению быстрого получения top m строк, как небольшое расширение получения top 1 строки.
Обсуждают сегодня