powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Что можно сделать для сокращения времени обработки запроса?
25 сообщений из 69, страница 1 из 3
Что можно сделать для сокращения времени обработки запроса?
    #39259400
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Запрос:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select *,(dist_start+dist_end) as sum_dist from 
(select osm_id as id_start, way as start_way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT(28.2789393 57.8155523)',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist_start
from ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes') t1,
(select osm_id as id_end, way as end_way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT(28.2951125 57.8141805)',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist_end
from ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes') t2,
opengeo.ru_psk_rels rels 
where array[id_start,id_end]<@rels.parts 
and array['route','ref']<@rels.tags 
and bus_idx_rels_parts(rels.id,id_start)<bus_idx_rels_parts(rels.id,id_end) limit 1
order by sum_dist limit 1;



Анализ:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
"Limit  (cost=3176.27..3176.27 rows=1 width=657) (actual time=5735.833..5735.839 rows=1 loops=1)"
"  ->  Sort  (cost=3176.27..3176.27 rows=1 width=657) (actual time=5735.799..5735.799 rows=1 loops=1)"
"        Sort Key: ((st_distance_spheroid(st_transform(opengeo.ru_psk_point.way, 4326), '0101000020E6100000B311E39068473C40BB568C0464E84C40'::geometry, 'SPHEROID("WGS 84",6378137,298.257223562997)'::spheroid) + st_distance_spheroid(st_transform(opengeo.ru_psk_point.way, 4326), '0101000020E61000000B24287E8C4B3C403D450E1137E84C40'::geometry, 'SPHEROID("WGS 84",6378137,298.257223562997)'::spheroid)))"
"        Sort Method: top-N heapsort  Memory: 19kB"
"        ->  Nested Loop  (cost=32.82..3176.26 rows=1 width=657) (actual time=9.605..5682.064 rows=4731 loops=1)"
"              ->  Nested Loop  (cost=0.00..3137.90 rows=1 width=272) (actual time=0.086..1831.338 rows=32761 loops=1)"
"                    ->  Seq Scan on ru_psk_point  (cost=0.00..1568.94 rows=1 width=136) (actual time=0.045..8.347 rows=181 loops=1)"
"                          Filter: ((public_transport = 'stop_position'::text) AND ((tags -> 'bus'::text) = 'yes'::text))"
"                          Rows Removed by Filter: 24330"
"                    ->  Seq Scan on ru_psk_point  (cost=0.00..1568.94 rows=1 width=136) (actual time=0.014..7.718 rows=181 loops=181)"
"                          Filter: ((public_transport = 'stop_position'::text) AND ((tags -> 'bus'::text) = 'yes'::text))"
"                          Rows Removed by Filter: 24330"
"              ->  Bitmap Heap Scan on ru_psk_rels rels  (cost=32.82..37.34 rows=1 width=385) (actual time=0.091..0.095 rows=0 loops=32761)"
"                    Recheck Cond: ((ARRAY[opengeo.ru_psk_point.osm_id, opengeo.ru_psk_point.osm_id] <@ parts) AND ('{route,ref}'::text[] <@ tags))"
"                    Filter: (bus_idx_rels_parts(id, opengeo.ru_psk_point.osm_id) < bus_idx_rels_parts(id, opengeo.ru_psk_point.osm_id))"
"                    Rows Removed by Filter: 0"
"                    ->  BitmapAnd  (cost=32.82..32.82 rows=1 width=0) (actual time=0.067..0.067 rows=0 loops=32761)"
"                          ->  Bitmap Index Scan on idx_ru_psk_rels_gin_parts  (cost=0.00..12.23 rows=31 width=0) (actual time=0.017..0.017 rows=0 loops=32761)"
"                                Index Cond: (ARRAY[opengeo.ru_psk_point.osm_id, opengeo.ru_psk_point.osm_id] <@ parts)"
"                          ->  Bitmap Index Scan on idx_ru_psk_rels_gin_tags  (cost=0.00..20.33 rows=44 width=0) (actual time=0.191..0.191 rows=499 loops=5735)"
"                                Index Cond: ('{route,ref}'::text[] <@ tags)"
"Total runtime: 5736.551 ms"


Если убрать ORDER, то время сразу устраивает в отличии от результата:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select *,(dist_start+dist_end) as sum_dist from 
(select osm_id as id_start, way as start_way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT(28.2789393 57.8155523)',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist_start
from ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes') t1,
(select osm_id as id_end, way as end_way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT(28.2951125 57.8141805)',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist_end
from ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes') t2,
opengeo.ru_psk_rels rels 
where array[id_start,id_end]<@rels.parts 
and array['route','ref']<@rels.tags 
and bus_idx_rels_parts(rels.id,id_start)<bus_idx_rels_parts(rels.id,id_end) limit 1



Анализ:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
"Limit  (cost=32.82..3176.26 rows=1 width=657) (actual time=11.365..11.371 rows=1 loops=1)"
"  ->  Nested Loop  (cost=32.82..3176.26 rows=1 width=657) (actual time=11.343..11.343 rows=1 loops=1)"
"        ->  Nested Loop  (cost=0.00..3137.90 rows=1 width=272) (actual time=0.082..0.525 rows=13 loops=1)"
"              ->  Seq Scan on ru_psk_point  (cost=0.00..1568.94 rows=1 width=136) (actual time=0.041..0.041 rows=1 loops=1)"
"                    Filter: ((public_transport = 'stop_position'::text) AND ((tags -> 'bus'::text) = 'yes'::text))"
"              ->  Seq Scan on ru_psk_point  (cost=0.00..1568.94 rows=1 width=136) (actual time=0.016..0.252 rows=13 loops=1)"
"                    Filter: ((public_transport = 'stop_position'::text) AND ((tags -> 'bus'::text) = 'yes'::text))"
"                    Rows Removed by Filter: 313"
"        ->  Bitmap Heap Scan on ru_psk_rels rels  (cost=32.82..37.34 rows=1 width=385) (actual time=0.312..0.312 rows=0 loops=13)"
"              Recheck Cond: ((ARRAY[opengeo.ru_psk_point.osm_id, opengeo.ru_psk_point.osm_id] <@ parts) AND ('{route,ref}'::text[] <@ tags))"
"              Filter: (bus_idx_rels_parts(id, opengeo.ru_psk_point.osm_id) < bus_idx_rels_parts(id, opengeo.ru_psk_point.osm_id))"
"              Rows Removed by Filter: 0"
"              ->  BitmapAnd  (cost=32.82..32.82 rows=1 width=0) (actual time=0.090..0.090 rows=0 loops=13)"
"                    ->  Bitmap Index Scan on idx_ru_psk_rels_gin_parts  (cost=0.00..12.23 rows=31 width=0) (actual time=0.028..0.028 rows=1 loops=13)"
"                          Index Cond: (ARRAY[opengeo.ru_psk_point.osm_id, opengeo.ru_psk_point.osm_id] <@ parts)"
"                    ->  Bitmap Index Scan on idx_ru_psk_rels_gin_tags  (cost=0.00..20.33 rows=44 width=0) (actual time=0.257..0.257 rows=499 loops=2)"
"                          Index Cond: ('{route,ref}'::text[] <@ tags)"
"Total runtime: 11.731 ms"

Нужна одна любая строчка с минимальной SUM_DIST.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259549
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

Вы статистику давно пересобирали? Во всех узлах ожидание 1 записи.

SeqScan-ы по `ru_psk_point` с фильтрацией — может индексы сделать?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259627
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovits_me,
SeqScan-ы по `ru_psk_point` с фильтрацией — может индексы сделать?

там копейки.
потом он берёт декартов квадрат 181*181 = 32761 (нельзя ли усечь до треугольника), умножает его декартово ещё на табличку -- и начинает фильтровать по функциональным критериям. потом сортирует опять по ф-ии, и берет первое.
ессно, всё это дорого.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259697
Alexius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

не совсем копейки, есть смысл индексы сделать, чтобы на секунду ускорить:

Код: sql
1.
"                    ->  Seq Scan on ru_psk_point  (cost=0.00..1568.94 rows=1 width=136) (actual time=0.014..7.718 rows=181 loops=181)"
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259705
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexiusqwwq,

не совсем копейки, есть смысл индексы сделать, чтобы на секунду ускорить:

неа, взять 1 цте, с обеими расстояниями, и квадратить уже его декартом. (а лучше -- таки треуголить, если по логике возможно).
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259708
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А можно поприземлённей немного выдать рекомендацию?)) Я уж точно ничего не декартил - просто написал запрос.))

По поводу индексов ru_psk_point, есть только 2:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
CREATE INDEX ru_psk_point_index
  ON ru_psk_point
  USING gist
  (way);

CREATE INDEX ru_psk_point_pkey
  ON ru_psk_point
  USING btree
  (osm_id);
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259787
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

декартите,, да ещё и со свистом

Код: sql
1.
2.
3.
4.
(select osm_id as id_start, way as start_way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT(28.2789393 57.8155523)',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist_start
from ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes') t1,
(select osm_id as id_end, way as end_way, ST_Distance_Spheroid(ST_Transform(way,4326), ST_GeomFromText('POINT(28.2951125 57.8141805)',4326), 'SPHEROID["WGS 84",6378137,298.257223563]') as dist_end
from ru_psk_point where public_transport='stop_position' and tags -> 'bus' = 'yes') t



-- это одна и та же выборка, но с разными расчетными расстояниями.
возьмите её как одно цте. и 2 раза попользуйте.


если не боитесь писать рукамидалее -- вы знаете, что расстояния неотрицательны (ну вот так вот оно)
и вы знаете, что сумма неотрицательных упорядочена где--то по слагаемым, с максимумами по диагонали слагаемых.

т.е. можете взять руками цте, и по нему рекурсивно например побежать от минимальных расстояний, проверяя фильтры по--ходу. а не сортируя итоговое произведение.

если рекурсивный запрос для вас сложен -- распишите в plpgsql двумя вложенными циклами. (там надо выскакивать не сразу, а когда одна из координат превзойдет минимальную ранее найденную сумму -- т.е. ограниченный сорт у вас останется)

но это суровый хенджоб тащемто, проще попытаться запинать вдвое, зная как у вас ориентировано это нечто (с какого конца по ид у вас старт, а с какого енд) -- вместо квадрата получите его половину . в 10 раз не выиграете -- но 2--ку наберете. ну и т.п.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259791
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

для начала что такое "цте"?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259795
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
и еще, изначально был вариант через циклы в функции(меньше предыдущего) - дольше, в итоге я у этого запроса сижу.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39259974
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_meqwwq,

для начала что такое "цте"?
ЦТЕ == CTE == Common Table Expression
Имеют эффект материализации (гарантированно исполняются только один раз).
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39260477
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqits_me,

т.е. можете взять руками цте, и по нему рекурсивно например побежать от минимальных расстояний, проверяя фильтры по--ходу. а не сортируя итоговое произведение.


Этот момент можете прояснить, у меня в голове несколько вариантов возникло, но что именно Вы имели ввиду(взять весь мой результат и прорекурсиветь или взять отдельную часть запроса прорекурсиветь и далее ее "соединить" и тп)?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39260508
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

у вас 181 запись с 2-- мя расстояниями, вы их декартово умножается на себя, расстояния складываются. получается 181*181 вариантов, которые вы фильтруете умножая эти 181*181 ещё на таблицу -- для фильтра. (вместо скажем екзистса)

потом результат сортируете по сумме расстояний, и берете 1 запись вдоль сортировки.

ясно, что вы можете бежать в двойном цикле по 2-м сортированным (по разному) экземплярам (по 191 записи), и найти первое попавшееся под итоговый фильтр.

вернее пробежаться чуть дальше -- до размера любой координаты в квадранте "не больше" первого найденного суммарного расстояния [далее => текущего минимального суммарного расстояния], и там немного посортировать (на самом -- на лету вычислять least), но гораздо меньше чем 181*181.

как--то так.

короче -- ищущий да обрящет.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39260524
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq,

Я только вчера узнал про рекурсивную выборку, а тут такое объяснение, зря спросил))))
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39260729
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_me,

Можете где-то дампы табличек выложить, поиграться?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39260885
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

Честно говоря даже не знаю как подойти к этому вопросу)
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39261047
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

есть такая ссылка:
https://www.dropbox.com/s/pbtn1qhgioruqh3/backup_tables.7z?dl=0

пойдёт?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39261602
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqits_me,

у вас 181 запись с 2-- мя расстояниями, вы их декартово умножается на себя, расстояния складываются. получается 181*181 вариантов, которые вы фильтруете умножая эти 181*181 ещё на таблицу -- для фильтра. (вместо скажем екзистса)

потом результат сортируете по сумме расстояний, и берете 1 запись вдоль сортировки.

ясно, что вы можете бежать в двойном цикле по 2-м сортированным (по разному) экземплярам (по 191 записи), и найти первое попавшееся под итоговый фильтр.

вернее пробежаться чуть дальше -- до размера любой координаты в квадранте "не больше" первого найденного суммарного расстояния [далее => текущего минимального суммарного расстояния], и там немного посортировать (на самом -- на лету вычислять least), но гораздо меньше чем 181*181.

как--то так.

короче -- ищущий да обрящет.

Вы тут имеете ввиду через функцию(циклы) или ЦТЕ?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265356
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwq
ясно, что вы можете бежать в двойном цикле по 2-м сортированным (по разному) экземплярам (по 191 записи), и найти первое попавшееся под итоговый фильтр.

вернее пробежаться чуть дальше -- до размера любой координаты в квадранте "не больше" первого найденного суммарного расстояния [далее => текущего минимального суммарного расстояния], и там немного посортировать (на самом -- на лету вычислять least), но гораздо меньше чем 181*181.

Кто-нибудь может перевести это на человеческий язык?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265395
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
its_meqwwqясно, что вы можете бежать в двойном цикле по 2-м сортированным (по разному) экземплярам (по 191 записи), и найти первое попавшееся под итоговый фильтр.

вернее пробежаться чуть дальше -- до размера любой координаты в квадранте "не больше" первого найденного суммарного расстояния [далее => текущего минимального суммарного расстояния], и там немного посортировать (на самом -- на лету вычислять least), но гораздо меньше чем 181*181.

Кто-нибудь может перевести это на человеческий язык?

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

можно и на пошаговый. но лень.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265419
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
маленький экзерсис для мозга:

вот например у вас есть неуникальный индекс
, для простоты по NOT NULL полю
, и вы выбираете вдоль него лимит 10
смотрите план -- постгрес правильно берет лимит вдоль индекса, профетчив всего 10 записей.

далее вы добавляете в свой order by, ПОСЛЕ своего индексированного поля, еще и ключевое поле -- для уникальности [повторяемости] сортировки -- смотрите план, и видите лимит после фетча всего и сортировки всего. и начинаете медленно охеревать с интеллектуальности оптимизатора.

недолго думая вы пишете выборку всего того, что не больше (по вашему полю), чем то, что найдено по предыдущему, неповторимому, условию "лимит 10", и делаете повторимый ордер бай лимит 10 от этой промежуточной выборки -- и берёте с полки пирожок с чувством СВ "глубокого удовлетворения".

вот когда этот экзерсис разберёте руками и поймете -- начнете что--то понимать и про прочую оптимизацию. А заодно -- про оптимизатор ПЖ.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265569
Jonhson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq
далее вы добавляете в свой order by, ПОСЛЕ своего индексированного поля, еще и ключевое поле -- для уникальности [повторяемости] сортировки -- смотрите план, и видите лимит после фетча всего и сортировки всего. и начинаете медленно охеревать с интеллектуальности оптимизатора.

добавить в order by в смысле или имеется ввиду подзапрос?
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265578
its_me
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqмаленький экзерсис для мозга:

вот например у вас есть неуникальный индекс
, для простоты по NOT NULL полю
, и вы выбираете вдоль него лимит 10
смотрите план -- постгрес правильно берет лимит вдоль индекса, профетчив всего 10 записей.

далее вы добавляете в свой order by, ПОСЛЕ своего индексированного поля, еще и ключевое поле -- для уникальности [повторяемости] сортировки -- смотрите план, и видите лимит после фетча всего и сортировки всего. и начинаете медленно охеревать с интеллектуальности оптимизатора.

недолго думая вы пишете выборку всего того, что не больше (по вашему полю), чем то, что найдено по предыдущему, неповторимому, условию "лимит 10", и делаете повторимый ордер бай лимит 10 от этой промежуточной выборки -- и берёте с полки пирожок с чувством СВ "глубокого удовлетворения".

вот когда этот экзерсис разберёте руками и поймете -- начнете что--то понимать и про прочую оптимизацию. А заодно -- про оптимизатор ПЖ.

Да дело не в объяснении, русских слов мало да ещё и присутствуют биржевые определения. Вообще я до Вашего объяснения сделал так: взял из первой строки(limit 1) первую сумму(быстро отрабатывает) и сделал в выборке не больше или равно этой суммы, а как гарантия того что не попадет самое большое сделал ORDER по dist_start например и время сократилось в 10-15 раз. Может Вы примерно такое имели ввиду.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265660
Jonhson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqвот например у вас есть неуникальный индекс
, для простоты по NOT NULL полю
, и вы выбираете вдоль него лимит 10
смотрите план -- постгрес правильно берет лимит вдоль индекса, профетчив всего 10 записей..


вот что получилось
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create table t12 (id int, var varchar(10));
CREATE TABLE
db1=# create index t12_ind on t12(id);
CREATE INDEX
db1=# insert into t12 select id, 'rrr'||id from (select generate_series(1, 100000) as id) t;
INSERT 0 100000
db1=# commit;
COMMIT
db1=# explain analyze select id from t12 limit 10;
                                                 QUERY PLAN                                                 
------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..0.15 rows=10 width=4) (actual time=0.010..0.013 rows=10 loops=1)
   ->  Seq Scan on t12  (cost=0.00..1541.00 rows=100000 width=4) (actual time=0.006..0.007 rows=10 loops=1)
 Planning time: 0.392 ms
 Execution time: 0.036 ms




т.е. таки по таблице скан, если я правильно понимаю план
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265708
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jonhson,

data
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
DROP SCHEMA IF EXISTS test CASCADE;

CREATE SCHEMA test   AUTHORIZATION postgres;


CREATE TABLE test.t (id int primary key,  f varchar(15) not null);
create index ON test.t (f);
INSERT INTO test.t (id,f) SELECT n , (n%1000)::text||'f' FROM generate_series(1, 200000) n;
ANALYZE test.t;



test:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
EXPLAIN (ANALYZE on, VERBOSE on, COSTS on, BUFFERS off, TIMING off )
SELECT id, f FROM test.t ORDER BY f LIMIT 10;
------
'Limit  (cost=0.42..0.92 rows=10 width=8) (actual rows=10 loops=1)'
'  Output: id, f'
'  ->  Index Scan using t_f_idx on test.t  (cost=0.42..9988.23 rows=200000 width=8) (actual rows=10 loops=1)'
'        Output: id, f'
'Planning time: 0.726 ms'
'Execution time: 0.080 ms'




2
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
EXPLAIN (ANALYZE on, VERBOSE on, COSTS on, BUFFERS off, TIMING off )
SELECT id, f FROM test.t ORDER BY f,id LIMIT 10;
-------------
'Limit  (cost=7382.93..7382.95 rows=10 width=8) (actual rows=10 loops=1)'
'  Output: id, f'
'  ->  Sort  (cost=7382.93..7882.93 rows=200000 width=8) (actual rows=10 loops=1)'
'        Output: id, f'
'        Sort Key: t.f, t.id'
'        Sort Method: top-N heapsort  Memory: 17kB'
'        ->  Seq Scan on test.t  (cost=0.00..3061.00 rows=200000 width=8) (actual rows=200000 loops=1)'
'              Output: id, f'
'Planning time: 0.300 ms'
'Execution time: 89.230 ms'




handjob
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
EXPLAIN (ANALYZE on, VERBOSE on, COSTS on, BUFFERS off, TIMING off )

SELECT id, f FROM test.t
WHERE f<=(SELECT max(f) FROM (SELECT f FROM test.t ORDER BY f LIMIT 10) foo )
 ORDER BY f,id LIMIT 10;
----------------
'Limit  (cost=4769.13..4769.16 rows=10 width=8) (actual rows=10 loops=1)'
'  Output: t.id, t.f'
'  InitPlan 1 (returns $0)'
'    ->  Aggregate  (cost=1.04..1.05 rows=1 width=4) (actual rows=1 loops=1)'
'          Output: max((t_1.f)::text)'
'          ->  Limit  (cost=0.42..0.92 rows=10 width=4) (actual rows=10 loops=1)'
'                Output: t_1.f'
'                ->  Index Only Scan using t_f_idx on test.t t_1  (cost=0.42..9988.23 rows=200000 width=4) (actual rows=10 loops=1)'
'                      Output: t_1.f'
'                      Heap Fetches: 10'
'  ->  Sort  (cost=4768.08..4934.74 rows=66667 width=8) (actual rows=10 loops=1)'
'        Output: t.id, t.f'
'        Sort Key: t.f, t.id'
'        Sort Method: top-N heapsort  Memory: 17kB'
'        ->  Bitmap Heap Scan on test.t  (cost=1433.09..3327.43 rows=66667 width=8) (actual rows=200 loops=1)'
'              Output: t.id, t.f'
'              Recheck Cond: ((t.f)::text <= $0)'
'              Heap Blocks: exact=200'
'              ->  Bitmap Index Scan on t_f_idx  (cost=0.00..1416.42 rows=66667 width=0) (actual rows=200 loops=1)'
'                    Index Cond: ((t.f)::text <= $0)'
'Planning time: 0.365 ms'
'Execution time: 0.968 ms'



особенно это приятно, когда какой--нито битмап скан вместо индекскана превращает лимит проходной по мердж джойну партиций в лимит после фулл апенда + сорта.
...
Рейтинг: 0 / 0
Что можно сделать для сокращения времени обработки запроса?
    #39265806
Jonhson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
explain analyze select id from t12 order by id limit 10;
                                                           QUERY PLAN                                                            
---------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.29..0.61 rows=10 width=4) (actual time=0.046..0.051 rows=10 loops=1)
   ->  Index Only Scan using t12_ind on t12  (cost=0.29..3148.29 rows=100000 width=4) (actual time=0.045..0.049 rows=10 loops=1)
         Heap Fetches: 10
 Planning time: 0.143 ms
 Execution time: 0.074 ms



когда сделал сорт (в моём тесте) , пошло по индексу. Правда что раньше мешало? ;)

а в вашем тесте не понял

Код: sql
1.
Index Scan using t_f_idx on test.t 



если вы берёте select id, f , при этом id нет в индексе по f
...
Рейтинг: 0 / 0
25 сообщений из 69, страница 1 из 3
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Что можно сделать для сокращения времени обработки запроса?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]