Быстрая сортировка

nevermind
Дата: 05.05.2004 18:57:05
В таблице до х... записей, база - часть web-проекта. Соотв-но время выполнения запросов критично. Выбираем записи с исп-ем limit - offset, однако понятно, что при добавлении сортировки по-любому полю время выполнения взлетает до бесконечности в отд. случаях. Вопрос: возможно ли как-нибудь контролировать сортировку по умолчанию дабы ни использовать order by и сохранить минииальное время на выполнение?

Спасибо!
CM Hungry
Дата: 05.05.2004 19:25:20
Индексы обычно делают по тем полям, по которым сортировка будет.
nevermind
Дата: 05.05.2004 19:45:12
Не помогает :( Еще есть предложения?
Leningrad
Дата: 05.05.2004 22:41:25
Тут пробегала статья, про настройку производительности...
"1.1 Не используйте настройки по умолчанию"
LeXa NalBat
Дата: 06.05.2004 10:28:13
при добавлении сортировки по-любому полю время выполнения взлетает до бесконечности в отд. случаях


Если в некотором запросе вместо indexscan-а используется seqscan и именно из-за этого "время выполнения взлетает до бесконечности", то надо построить индекс по нужным полям (которые указаны в order by), и например обязательно включить в order by (и в индекс) поля, на которые наложены ограничения на равенство в условии where.

Не помогает :(


Приведите пример вашей таблицы и медленно выполняющегося запроса.

Выбираем записи с исп-ем limit - offset


Если в запросе большой offset, то постгрес должен прочитать это большое число записей прежде чем начнет выдавать результат. У меня запрос "select id from foo order by id limit 10" работает 0.15 секунды, а запрос "select id from foo order by id offset 1000000 limit 10" - 3.5 секунды. Как побороть такое замедление, не знаю. :-( Может быть ввести поле ordr, которое будет упорядочено как id, но принимать последовательные натуральные значения начиная с 1 - тогда второй запрос надо переписать так: "select id from foo where ordr > 1000000 order by ordr limit 10", и он будет выполняться быстро. Однако как в этом случае быстро добавлять строки с id<max(id), удалять строки?

Вопрос: возможно ли как-нибудь контролировать сортировку по умолчанию дабы ни использовать order by и сохранить минииальное время на выполнение?


Нельзя.
nevermind
Дата: 06.05.2004 12:53:29
ВСЕМ ОГРОМНОЕ СПАСИБО!!! РАЗОБРАЛСЯ!!! :)
k
Дата: 18.08.2004 18:19:52
Вариант с where не катит в том случае если offset пока ещё не очень велик по отношению к количеству записей, т.к. оптимизатор предпочитает не
использовать индекс в этом случае, даже при условии небольшого limit.

Решение - использовать ограничение сверху, но это не всегда реально сделать точно.
LeXa NalBat
Дата: 18.08.2004 18:47:38
оптимизатор предпочитает не использовать индекс в этом случае, даже при условии небольшого limit


может быть вы забыли указать order by? (limit без order by - ошибка)

pl=# select min(plno), max(plno), count(plno) from plprice_00;
min | max | count
--------+-----------+---------
465785 | 165664562 | 2741431
(1 row)

pl=# explain select plno from plprice_00 where plno > 465785;
QUERY PLAN
---------------------------------------------------------------------
Seq Scan on plprice_00 (cost=0.00..161261.89 rows=2741157 width=4)
Filter: (plno > 465785)
(2 rows)

pl=# explain select plno from plprice_00 where plno > 465785 limit 25;
QUERY PLAN
---------------------------------------------------------------------------
Limit (cost=0.00..1.47 rows=25 width=4)
-> Seq Scan on plprice_00 (cost=0.00..161261.89 rows=2741157 width=4)
Filter: (plno > 465785)
(3 rows)

pl=# explain select plno from plprice_00 where plno > 465785 order by plno limit 25;
QUERY PLAN
--------------------------------------------------------------------------------------------------
Limit (cost=0.00..1.57 rows=25 width=4)
-> Index Scan using pk_prc_plno_00 on plprice_00 (cost=0.00..172357.35 rows=2741157 width=4)
Index Cond: (plno > 465785)
(3 rows)
k
Дата: 18.08.2004 20:25:30
да, действительно. :)
спасибо за подсказку