Postgresql COALESCE našumo problema

Turiu šią lentelę Postgresql:

 CREATE TABLE my_table ( id bigint NOT NULL, value bigint, CONSTRAINT my_table_pkey PRIMARY KEY (id) ); 

„My_table“ yra ~ 50 000 eilučių.

Kyla klausimas, kodėl prašymas:

 SELECT * FROM my_table WHERE id = COALESCE(null, id) and value = ? 

lėčiau nei tai:

 SELECT * FROM my_table WHERE value = ? 

Ar yra koks nors kitas sprendimas, išskyrus užklausų eilutės optimizavimą taikomųjų programų lygmenyje?

EDIT: Praktiškai kyla klausimas, kaip perrašyti užklausą select * from my_table where id=coalesce(?, id) and value=? taip, kad blogiausio atvejo našumas būtų mažesnis nei select * from my_table where value=? postgresql 9.0

5
21 июня '11 в 16:53 2011-06-21 16:53 „Tair“ yra nustatytas birželio 21 d. 11 val. 16:53 2011-06-21 16:53
@ 2 atsakymai

Pabandykite perrašyti formos užklausą.

 SELECT * FROM my_table WHERE value = ? AND (? IS NULL OR id = ?) 

Iš savo greito testo

 INSERT INTO my_table select generate_series(1,50000),1; UPDATE my_table SET value = id%17; CREATE INDEX val_idx ON my_table(value); VACUUM ANALYZE my_table; \set idval 17 \set pval 0 explain analyze SELECT * FROM my_table WHERE value = :pval AND (:idval IS NULL OR id = :idval); Index Scan using my_table_pkey on my_table (cost=0.00..8.29 rows=1 width=16) (actual time=0.034..0.035 rows=1 loops=1) Index Cond: (id = 17) Filter: (value = 0) Total runtime: 0.064 ms \set idval null explain analyze SELECT * FROM my_table WHERE value = :pval AND (:idval IS NULL OR id = :idval); Bitmap Heap Scan on my_table (cost=58.59..635.62 rows=2882 width=16) (actual time=0.373..1.594 rows=2941 loops=1) Recheck Cond: (value = 0) -> Bitmap Index Scan on validx (cost=0.00..57.87 rows=2882 width=0) (actual time=0.324..0.324 rows=2941 loops=1) Index Cond: (value = 0) Total runtime: 1.811 ms 
3
23 июня '11 в 11:43 2011-06-23 11:43 atsakymą pateikė Gavinas birželio 23 d. 11 val. 11:43 2011-06-23 11:43

Panašios lentelės sukūrimas, užpildymas, statistinių duomenų atnaujinimas ir galiausiai ieškant „ EXPLAIN ANALYZE , vienintelis skirtumas, kurį matau, yra tai, kad pirmieji užklausų filtrai tokie:

 Filter: ((id = COALESCE(id)) AND (value = 3)) 

ir antrasis - taip:

 Filter: (value = 3) 

Matydamas rodyklę „Vertė“ stulpelyje, pastebiu gerokai skirtingus veiklos ir vykdymo planus. Pirmuoju atveju

 Bitmap Heap Scan on my_table (cost=19.52..552.60 rows=5 width=16) (actual time=19.311..20.679 rows=1000 loops=1) Recheck Cond: (value = 3) Filter: (id = COALESCE(id)) -> Bitmap Index Scan on t2 (cost=0.00..19.52 rows=968 width=0) (actual time=19.260..19.260 rows=1000 loops=1) Index Cond: (value = 3) Total runtime: 22.138 ms 

ir antroje

 Bitmap Heap Scan on my_table (cost=19.76..550.42 rows=968 width=16) (actual time=0.302..1.293 rows=1000 loops=1) Recheck Cond: (value = 3) -> Bitmap Index Scan on t2 (cost=0.00..19.52 rows=968 width=0) (actual time=0.276..0.276 rows=1000 loops=1) Index Cond: (value = 3) Total runtime: 2.174 ms 

Taigi, sakyčiau, kad tai yra lėtesnė, nes db a) mechanizmas įvertina COALESCE () išraišką, o ne optimizuoja, ir b) jo vertinimas apima papildomą filtro būklę.

2
21 июня '11 в 19:15 2011-06-21 19:15 atsakė Mike Sherrill 'Cat Recall'ui „ Birželio 21 '11, 19:15, 2011-06-21 19:15

Kiti klausimai, susiję su „ žymėmis, arba užduoti klausimą