Имея тестовую таблицу, как это:Postgres не использует индекс над определенным лимитом строк?
testdb=> \d test_table
Table "public.test_table"
Column | Type | Modifiers
----------------------------+-----------------------------+-----------------------------------------------------------
id | integer | not null default nextval('test_table_id_seq'::regclass)
phone | character varying(15) | not null
comment | text |
timestamp | timestamp without time zone | not null
Indexes:
"test_table_pkey" PRIMARY KEY, btree (id)
"i_test_substr" btree ("substring"(phone::text, 1, 1), "timestamp" DESC)
Triggers:
С индексом, как это:
testdb=> create index i_test_substr ON test_table (substring(phone, 1, 1), timestamp desc);
Эти запросы будут использовать индекс для сортировки в соответствии с лимитом 203 строк, но будет сортировать в памяти выше 204 строк.
Может ли кто-нибудь объяснить это поведение?
testdb=> explain analyze select * from test_table where substring(phone,1 ,1) = '2' order by timestamp desc limit 203;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.42..709.52 rows=203 width=202) (actual time=0.043..0.194 rows=203 loops=1)
-> Index Scan using i_test_substr on test_table (cost=0.42..1146.16 rows=328 width=202) (actual time=0.041..0.170 rows=203 loops=1)
Index Cond: ("substring"((phone)::text, 1, 1) = '2'::text)
Total runtime: 0.249 ms
(4 rows)
testdb=> explain analyze select * from test_table where substring(phone,1 ,1) = '2' order by timestamp desc limit 204;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=711.74..712.25 rows=204 width=202) (actual time=7.655..7.681 rows=204 loops=1)
-> Sort (cost=711.74..712.56 rows=328 width=202) (actual time=7.653..7.664 rows=204 loops=1)
Sort Key: "timestamp"
Sort Method: top-N heapsort Memory: 53kB
-> Bitmap Heap Scan on test_table (cost=10.96..698.03 rows=328 width=202) (actual time=1.340..5.010 rows=11514 loops=1)
Recheck Cond: ("substring"((phone)::text, 1, 1) = '2'::text)
-> Bitmap Index Scan on i_test_substr (cost=0.00..10.88 rows=328 width=0) (actual time=1.217..1.217 rows=11514 loops=1)
Index Cond: ("substring"((phone)::text, 1, 1) = '2'::text)
Total runtime: 7.746 ms
(9 rows)
Пожалуйста, приложите гранулярность таблицы и количество строк запроса без ограничений + объясните анализ без ограничений –
'vacuum',' analyse', 'reindex' не помогло? – devanand
Вот как работает оптимизатор. См. Bruce Momjan слайды об этом на странице https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjCl9G05JXLAhVJDxoKHRfCAQcQFgggMAA&url=https%3A%2F%2Fmomjian.us%2Fmain % 2Fwritings% 2Fpgsql% 2Foptimizer.pdf & USG = AFQjCNGDzCTCJt0n7BTrr_nqgfZIQMAUWQ & Sig2 = k_gYi_rSo3J-SvSel1saqA – greg