powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / медленный index scan + limit
7 сообщений из 32, страница 2 из 2
медленный index scan + limit
    #39569937
Dany305
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fteDany305,

Dany305для обычных таблиц эти значения близки и особой разницы нет, но для очередей это не так
а эта таблица работает как очередь - интенсивно лопатиться, но живых записей мало
после analyze в reltuples запишется маленькое число и планировщик будет выбирать быстрый seq scan
после vacuum в reltuples запишется большое число и планировщик будет выбирать медленный index scan

+1
ИМНО: индивидуальные(агрессивные) настройки autovacuum для таблицы должны помочь...

вряд ли помогут в решение данной проблемы,
кажется не существует настроек autovacuum,
которые бы гарантировали порядок исполнения: vacuum, analyze

в сходной проблеме мне помогло выключение autovacuum + ручной vacuum analyze
...
Рейтинг: 0 / 0
медленный index scan + limit
    #39569938
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dany305,
тут же всё расписано :
//думается кост из инд-скана не берется, а берется из лимита (т.к. ре--сорта нет)
если это не так -- они ещё тупее, чем я думайу

kukurzik ...
дело в селективности, при определенном пороге пж переключается
с правильного индекса (клиент, ид) на "неправильный"(ид)

Код: 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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
explain (analyze, buffers)
SELECT *
FROM transfers
WHERE client_number = ?
ORDER BY    id
limit 50

-- 0.01 %
"Limit  (cost=0.43..193.65 rows=50 width=659) (actual time=0.050..0.180 rows=50 loops=1)"
"  Buffers: shared hit=53"
"  ->  Index Scan using transfers_client_number_id_idx on transfers  (cost=0.43..5557.34 rows=1438 width=659) (actual time=0.048..0.171 rows=50 loops=1)"
"        Index Cond: (client_number = 60)"
"        Buffers: shared hit=53"
"Planning time: 0.299 ms"
"Execution time: 0.255 ms"

-- ~2.5%
"Limit  (cost=0.43..116.76 rows=50 width=659) (actual time=0.030..0.109 rows=50 loops=1)"
"  Buffers: shared hit=53"
"  ->  Index Scan using transfers_client_number_id_idx on transfers  (cost=0.43..493100.92 rows=211947 width=659) (actual time=0.029..0.104 rows=50 loops=1)"
"        Index Cond: (client_number = 831)"
"        Buffers: shared hit=53"
"Planning time: 0.178 ms"
"Execution time: 0.142 ms"

-- ~6.5% и праздник закончился
"Limit  (cost=0.43..51.22 rows=50 width=659) (actual time=450.099..450.271 rows=50 loops=1)"
--- тут равномерная модель с фильтрацией 7% вдоль ПК оказалась перекосоёбленной
--- но она строго мясимясисьсьски ВСЕГДА херовее прямой выборки по спец инд-у БЕЗ фильтра
-- мораль -- сидеть и не чирикать, пока не отползут из этого чуда 
-- и даже на мускуль не гнать волну, или там фаерберда
"  Buffers: shared hit=692852"
"  ->  Index Scan using transfers_pkey on transfers  (cost=0.43..604537.41 rows=595121 width=659) (actual time=450.097..450.266 rows=50 loops=1)"
"        Filter: (client_number = 110)"
"        Rows Removed by Filter: 951480"
"        Buffers: shared hit=692852"
"Planning time: 0.388 ms"
"Execution time: 450.332 ms"



за счет чего так просела стоимость лимита по пк -- не ясно. неужели за счет одной лишь ширины инлекса ? на 50 записей доступов д.б. с гулькин нос (по спецу). а в пк же множитель 100/7 как минимум д.б. в костах ? с какого потолка он 51.22 высосал ? или кост этих 100/7 ещё где--то отдельно написан ?
-- судя по всему -- там все херово даже с арифметикой.


или пусть кто--то разъяснит, как стоимость лимита вдоль выборки (без ресорта) расписана в плане . не собирается же он сначала выфетчить унутре в себя те самые 1438, по цене 5557.34
Код: plaintext
"  ->  Index Scan using transfers_client_number_id_idx on transfers  (cost=0.43..5557.34 rows=1438 width=659) ...)"
и токмо опосля лимитится
(на кой хер там вообще эта цифра ?или стюдент 100 лет тому написал -- и хай буде ?)
...
Рейтинг: 0 / 0
медленный index scan + limit
    #39569944
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqили пусть кто--то разъяснит, как стоимость лимита вдоль выборки (без ресорта) расписана в плане . не собирается же он сначала выфетчить унутре в себя те самые 1438, по цене 5557.34
Код: plaintext
"  ->  Index Scan using transfers_client_number_id_idx on transfers  (cost=0.43..5557.34 rows=1438 width=659) ...)"
и токмо опосля лимитится
Ну вот потому и считается оценка как 2 числа: цена вывода первых записей в узле и цена на всю работу узла. Собственно, цена вывода первых записей (первая цена) и используется в случаях с LIMIT. Как оно оценивается для LIMIT 1 и/или LIMIT 50 я точно не скажу, надо в исходники лезть.
...
Рейтинг: 0 / 0
медленный index scan + limit
    #39618932
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вдогонку:

из 2-х индексов not unique (id) , unique (id,indexed) при линковке по id и без выборки поля "индексед" планер выбирает составной уникъю. (при неуникальности ид в десятые процента)

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

забавно.
...
Рейтинг: 0 / 0
медленный index scan + limit
    #39619040
Alexius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqвдогонку:

из 2-х индексов not unique (id) , unique (id,indexed) при линковке по id и без выборки поля "индексед" планер выбирает составной уникъю. (при неуникальности ид в десятые процента)

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

забавно.

а индекс по id точно более компактный (если \di+ indexname cравнить) ?
...
Рейтинг: 0 / 0
медленный index scan + limit
    #39619068
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexiusа индекс по id точно более компактный (если \di+ indexname cравнить) ?
их у меня 90 штук. т.ч. какие-то точно компактнее.

вернее на паре кейсов отреиндексил (ещё тогда) оба -- поведение не изменилось.
отпишусь позже -- сейчас дисковую нагрузил замером.

и да, пж умеет извлекать из уникальности поправки к планам и костам (по лейтералам из пк видно -- планирует по 1). но кажется не умеет обобществлять общезначимые следствия из. (так же как выше по теме получая лучший план из недостаточной модели (равновероятности неизвестного)-- пренебрегает "худшим" из точного индекса-- отбросить дурной оптимистический план, который де-факто д.б. зарезан планом по верному индексу он не умеет)
...
Рейтинг: 0 / 0
медленный index scan + limit
    #39619327
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexius,

сделал
Код: sql
1.
ALTER DATABASE jsons  SET default_statistics_target = '1000';


переиндексировал (чтобы без дырок) и аналайзнул.

появились сканы по узкому инд-у. но остались и по широкому (если записей в плане мало).



Код: sql
1.
2.
3.
4.
5.
"Nested Loop  (cost=0.85..120713.14 rows=8339 width=28)"
"  ->  Index Only Scan using listofdoi_pkey on listofdoi l  (cost=0.43..1159.55 rows=22156 width=24)"
"        Index Cond: ((doi >= '10.1001/10-v4n2-hsf10003'::text) AND (doi <= '10.1002/9780470166123.indsub'::text))"
"  ->  Index Scan using jitems_0000_doi_idx on jitems_0000 t  (cost=0.42..5.39 rows=1 width=38)"
"        Index Cond: (doi = l.doi)"



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SELECT l.doi 
	,"is-referenced-by-count" 
FROM public.listofdoi  l inner join   doi.jitems_0092 t on t.doi = l.doi
WHERE   l.doi between '10.5300/2001-4/153' AND '10.5840/gps1992439';
---------------
"Nested Loop  (cost=0.85..766.96 rows=34 width=28) (actual time=0.120..17.216 rows=2379 loops=1)"
"  ->  Index Only Scan using listofdoi_pkey on listofdoi l  (cost=0.43..6.23 rows=90 width=24) (actual time=0.085..0.703 rows=2578 loops=1)"
"        Index Cond: ((doi >= '10.5300/2001-4/153'::text) AND (doi <= '10.5840/gps1992439'::text))"
"        Heap Fetches: 0"
"  ->  Index Scan using "jitems_0092_doi_indexed.date-time_idx" on jitems_0092 t  (cost=0.42..8.44 rows=1 width=28) (actual time=0.006..0.006 rows=1 loops=2578)"
"        Index Cond: (doi = l.doi)"
"Planning time: 3.360 ms"
"Execution time: 17.339 ms"
-----------------------------
 Schema |                 Name                  | Type  |  Owner   |    Table    | Size  | Description 
--------+---------------------------------------+-------+----------+-------------+-------+-------------
 doi    | jitems_0092_doi_indexed.date-time_idx | index | postgres | jitems_0092 | 52 MB | 

--тут по уникъю планируется

drop UNIQUE:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
"Nested Loop  (cost=0.85..766.96 rows=34 width=28) (actual time=0.121..16.827 rows=2379 loops=1)"
"  ->  Index Only Scan using listofdoi_pkey on listofdoi l  (cost=0.43..6.23 rows=90 width=24) (actual time=0.086..0.681 rows=2578 loops=1)"
"        Index Cond: ((doi >= '10.5300/2001-4/153'::text) AND (doi <= '10.5840/gps1992439'::text))"
"        Heap Fetches: 0"
"  ->  Index Scan using jitems_0092_doi_idx on jitems_0092 t  (cost=0.42..8.44 rows=1 width=28) (actual time=0.006..0.006 rows=1 loops=2578)"
"        Index Cond: (doi = l.doi)"
"Planning time: 3.256 ms"
"Execution time: 16.943 ms"
-----------------
 Schema |        Name         | Type  |  Owner   |    Table    | Size  | Description 
--------+---------------------+-------+----------+-------------+-------+-------------
 doi    | jitems_0092_doi_idx | index | postgres | jitems_0092 | 43 MB | 



и , при массовом плане от 2--5% ожидаемо падаем в хеш
Код: sql
1.
2.
3.
4.
5.
6.
"Hash Join  (cost=3098.77..156501.77 rows=18000 width=28)"
"  Hash Cond: (t.doi = l.doi)"
"  ->  Seq Scan on jitems_0001 t  (cost=0.00..149473.00 rows=1000000 width=29)"
"  ->  Hash  (cost=2500.95..2500.95 rows=47826 width=24)"
"        ->  Index Only Scan using listofdoi_pkey on listofdoi l  (cost=0.43..2500.95 rows=47826 width=24)"
"              Index Cond: ((doi >= '10.1002/9780470166130'::text) AND (doi <= '10.1002/art.1780380723'::text))"




при таргете в 500 все было либо хешем, либо по уникъю.

откачусь. там интереснее. если поймаю разницу в планах по ожиданиям -- отпишусь.

пока же резюме -- при равных костах предпочитается уникъю, даже если шире.
...
Рейтинг: 0 / 0
7 сообщений из 32, страница 2 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / медленный index scan + limit
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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