我正在进行全文PostgreSQL搜索,我注意到只需在'<>'上更改我的某个过滤条件下的运算符to'='大大增加了查询时间,从24.7 ms到3979 ms。我在下面发布了explain analyze输出。我正在操作的列是'region_id',其数据类型是bigint。
关于为什么这么慢的想法?
感谢。
Limit (cost=0.00..330941.18 rows=50 width=12) (actual time=0.752..24.278 rows=50 loops=1)
-> Index Scan Backward using date_idx on article (cost=0.00..2574722.38 rows=389 width=12) (actual time=0.742..24.216 rows=50 loops=1)
Index Cond: ((date >= '2009-10-25'::date) AND (date <= '2014-11-24'::date))
Filter: ((region_id <> 15) AND (tsv @@ to_tsquery('((((((((((((((((((((asia) | (pacific)) | (china)) | (india)) | (indonesia)) | (pakistan)) | (bangladesh)) | (japan)) | (philippines)) | (vietnam)) | (thailand)) | (burma)) | (south & korea)) | (afghanistan)) | (nepal)) | (malaysia)) | (uzbekistan)) | (north & korea)) | (taiwan)) | (australia))'::text)) AND (((tsv @@ to_tsquery('(asia)'::text)) AND (body ~~* '%asia%'::text)) OR ((tsv @@ to_tsquery('(pacific)'::text)) AND (body ~~* '%pacific%'::text)) OR ((tsv @@ to_tsquery('(china)'::text)) AND (body ~~* '%china%'::text)) OR ((tsv @@ to_tsquery('(india)'::text)) AND (body ~~* '%india%'::text)) OR ((tsv @@ to_tsquery('(indonesia)'::text)) AND (body ~~* '%indonesia%'::text)) OR ((tsv @@ to_tsquery('(pakistan)'::text)) AND (body ~~* '%pakistan%'::text)) OR ((tsv @@ to_tsquery('(bangladesh)'::text)) AND (body ~~* '%bangladesh%'::text)) OR ((tsv @@ to_tsquery('(japan)'::text)) AND (body ~~* '%japan%'::text)) OR ((tsv @@ to_tsquery('(philippines)'::text)) AND (body ~~* '%philippines%'::text)) OR ((tsv @@ to_tsquery('(vietnam)'::text)) AND (body ~~* '%vietnam%'::text)) OR ((tsv @@ to_tsquery('(thailand)'::text)) AND (body ~~* '%thailand%'::text)) OR ((tsv @@ to_tsquery('(burma)'::text)) AND (body ~~* '%burma%'::text)) OR ((tsv @@ to_tsquery('(south & korea)'::text)) AND (body ~~* '%south korea%'::text)) OR ((tsv @@ to_tsquery('(afghanistan)'::text)) AND (body ~~* '%afghanistan%'::text)) OR ((tsv @@ to_tsquery('(nepal)'::text)) AND (body ~~* '%nepal%'::text)) OR ((tsv @@ to_tsquery('(malaysia)'::text)) AND (body ~~* '%malaysia%'::text)) OR ((tsv @@ to_tsquery('(uzbekistan)'::text)) AND (body ~~* '%uzbekistan%'::text)) OR ((tsv @@ to_tsquery('(north & korea)'::text)) AND (body ~~* '%north korea%'::text)) OR ((tsv @@ to_tsquery('(taiwan)'::text)) AND (body ~~* '%taiwan%'::text)) OR ((tsv @@ to_tsquery('(australia)'::text)) AND (body ~~* '%australia%'::text))))
Total runtime: 24.704 ms
这是我更改'region_id&lt;&gt;之后的解释分析输出15'到'region_id = 15'。
Limit (cost=275163.14..275163.18 rows=16 width=12) (actual time=3978.517..3978.550 rows=50 loops=1)
-> Sort (cost=275163.14..275163.18 rows=16 width=12) (actual time=3978.508..3978.522 rows=50 loops=1)
Sort Key: date
Sort Method: top-N heapsort Memory: 27kB
-> Bitmap Heap Scan on article (cost=44418.98..275162.82 rows=16 width=12) (actual time=425.783..3970.721 rows=6808 loops=1)
Recheck Cond: ((region_id = 15) AND (date >= '2009-10-25'::date) AND (date <= '2014-11-24'::date))
Filter: ((tsv @@ to_tsquery('((((((((((((((((((((asia) | (pacific)) | (china)) | (india)) | (indonesia)) | (pakistan)) | (bangladesh)) | (japan)) | (philippines)) | (vietnam)) | (thailand)) | (burma)) | (south & korea)) | (afghanistan)) | (nepal)) | (malaysia)) | (uzbekistan)) | (north & korea)) | (taiwan)) | (australia))'::text)) AND (((tsv @@ to_tsquery('(asia)'::text)) AND (body ~~* '%asia%'::text)) OR ((tsv @@ to_tsquery('(pacific)'::text)) AND (body ~~* '%pacific%'::text)) OR ((tsv @@ to_tsquery('(china)'::text)) AND (body ~~* '%china%'::text)) OR ((tsv @@ to_tsquery('(india)'::text)) AND (body ~~* '%india%'::text)) OR ((tsv @@ to_tsquery('(indonesia)'::text)) AND (body ~~* '%indonesia%'::text)) OR ((tsv @@ to_tsquery('(pakistan)'::text)) AND (body ~~* '%pakistan%'::text)) OR ((tsv @@ to_tsquery('(bangladesh)'::text)) AND (body ~~* '%bangladesh%'::text)) OR ((tsv @@ to_tsquery('(japan)'::text)) AND (body ~~* '%japan%'::text)) OR ((tsv @@ to_tsquery('(philippines)'::text)) AND (body ~~* '%philippines%'::text)) OR ((tsv @@ to_tsquery('(vietnam)'::text)) AND (body ~~* '%vietnam%'::text)) OR ((tsv @@ to_tsquery('(thailand)'::text)) AND (body ~~* '%thailand%'::text)) OR ((tsv @@ to_tsquery('(burma)'::text)) AND (body ~~* '%burma%'::text)) OR ((tsv @@ to_tsquery('(south & korea)'::text)) AND (body ~~* '%south korea%'::text)) OR ((tsv @@ to_tsquery('(afghanistan)'::text)) AND (body ~~* '%afghanistan%'::text)) OR ((tsv @@ to_tsquery('(nepal)'::text)) AND (body ~~* '%nepal%'::text)) OR ((tsv @@ to_tsquery('(malaysia)'::text)) AND (body ~~* '%malaysia%'::text)) OR ((tsv @@ to_tsquery('(uzbekistan)'::text)) AND (body ~~* '%uzbekistan%'::text)) OR ((tsv @@ to_tsquery('(north & korea)'::text)) AND (body ~~* '%north korea%'::text)) OR ((tsv @@ to_tsquery('(taiwan)'::text)) AND (body ~~* '%taiwan%'::text)) OR ((tsv @@ to_tsquery('(australia)'::text)) AND (body ~~* '%australia%'::text))))
-> BitmapAnd (cost=44418.98..44418.98 rows=80194 width=0) (actual time=424.591..424.591 rows=0 loops=1)
-> Bitmap Index Scan on article_region_idx (cost=0.00..2626.27 rows=129281 width=0) (actual time=31.828..31.828 rows=130290 loops=1)
Index Cond: (region_id = 15)
-> Bitmap Index Scan on date_idx (cost=0.00..41792.45 rows=1991585 width=0) (actual time=387.058..387.058 rows=2012923 loops=1)
Index Cond: ((date >= '2009-10-25'::date) AND (date <= '2014-11-24'::date))
Total runtime: 3979.345 ms
这是我原来的选择查询:
SELECT article_id
from article
WHERE
( tsv @@ to_tsquery('((((((((((((((((((((asia) | (pacific)) | (china)) | (india)) | (indonesia)) | (pakistan)) | (bangladesh)) | (japan)) | (philippines)) | (vietnam)) | (thailand)) | (burma)) | (south & korea)) | (afghanistan)) | (nepal)) | (malaysia)) | (uzbekistan)) | (north & korea)) | (taiwan)) | (australia))') )
and ((((((((((((((((((((tsv @@ to_tsquery('(asia)') and body ilike '%asia%') or (tsv @@ to_tsquery('(pacific)') and body ilike '%pacific%')) or (tsv @@ to_tsquery('(china)') and body ilike '%china%')) or (tsv @@ to_tsquery('(india)') and body ilike '%india%')) or (tsv @@ to_tsquery('(indonesia)') and body ilike '%indonesia%')) or (tsv @@ to_tsquery('(pakistan)') and body ilike '%pakistan%')) or (tsv @@ to_tsquery('(bangladesh)') and body ilike '%bangladesh%')) or (tsv @@ to_tsquery('(japan)') and body ilike '%japan%')) or (tsv @@ to_tsquery('(philippines)') and body ilike '%philippines%')) or (tsv @@ to_tsquery('(vietnam)') and body ilike '%vietnam%')) or (tsv @@ to_tsquery('(thailand)') and body ilike '%thailand%')) or (tsv @@ to_tsquery('(burma)') and body ilike '%burma%')) or (tsv @@ to_tsquery('(south & korea)') and body ilike '%south korea%')) or (tsv @@ to_tsquery('(afghanistan)') and body ilike '%afghanistan%')) or (tsv @@ to_tsquery('(nepal)') and body ilike '%nepal%')) or (tsv @@ to_tsquery('(malaysia)') and body ilike '%malaysia%')) or (tsv @@ to_tsquery('(uzbekistan)') and body ilike '%uzbekistan%')) or (tsv @@ to_tsquery('(north & korea)') and body ilike '%north korea%')) or (tsv @@ to_tsquery('(taiwan)') and body ilike '%taiwan%')) or (tsv @@ to_tsquery('(australia)') and body ilike '%australia%'))
AND region_id = 15
AND ( date >= '20091025' ) AND ( date <= '20141124' )
ORDER BY date DESC
LIMIT 50 OFFSET 0;
当我设置enable_bitmapscan = off时,这是解释输出:
Limit (cost=411239.49..411239.53 rows=16 width=1205) (actual time=3804.234..3804.263 rows=50 loops=1)
-> Sort (cost=411239.49..411239.53 rows=16 width=1205) (actual time=3804.224..3804.234 rows=50 loops=1)
Sort Key: date
Sort Method: top-N heapsort Memory: 117kB
-> Index Scan using article_region_idx on article (cost=0.00..411239.17 rows=16 width=1205) (actual time=0.555..3790.489 rows=6808 loops=1)
Index Cond: (region_id = 15)
Filter: ((date >= '2009-10-25'::date) AND (date <= '2014-11-24'::date) AND (tsv @@ to_tsquery('((((((((((((((((((((asia) | (pacific)) | (china)) | (india)) | (indonesia)) | (pakistan)) | (bangladesh)) | (japan)) | (philippines)) | (vietnam)) | (thailand)) | (burma)) | (south & korea)) | (afghanistan)) | (nepal)) | (malaysia)) | (uzbekistan)) | (north & korea)) | (taiwan)) | (australia))'::text)) AND (((tsv @@ to_tsquery('(asia)'::text)) AND (body ~~* '%asia%'::text)) OR ((tsv @@ to_tsquery('(pacific)'::text)) AND (body ~~* '%pacific%'::text)) OR ((tsv @@ to_tsquery('(china)'::text)) AND (body ~~* '%china%'::text)) OR ((tsv @@ to_tsquery('(india)'::text)) AND (body ~~* '%india%'::text)) OR ((tsv @@ to_tsquery('(indonesia)'::text)) AND (body ~~* '%indonesia%'::text)) OR ((tsv @@ to_tsquery('(pakistan)'::text)) AND (body ~~* '%pakistan%'::text)) OR ((tsv @@ to_tsquery('(bangladesh)'::text)) AND (body ~~* '%bangladesh%'::text)) OR ((tsv @@ to_tsquery('(japan)'::text)) AND (body ~~* '%japan%'::text)) OR ((tsv @@ to_tsquery('(philippines)'::text)) AND (body ~~* '%philippines%'::text)) OR ((tsv @@ to_tsquery('(vietnam)'::text)) AND (body ~~* '%vietnam%'::text)) OR ((tsv @@ to_tsquery('(thailand)'::text)) AND (body ~~* '%thailand%'::text)) OR ((tsv @@ to_tsquery('(burma)'::text)) AND (body ~~* '%burma%'::text)) OR ((tsv @@ to_tsquery('(south & korea)'::text)) AND (body ~~* '%south korea%'::text)) OR ((tsv @@ to_tsquery('(afghanistan)'::text)) AND (body ~~* '%afghanistan%'::text)) OR ((tsv @@ to_tsquery('(nepal)'::text)) AND (body ~~* '%nepal%'::text)) OR ((tsv @@ to_tsquery('(malaysia)'::text)) AND (body ~~* '%malaysia%'::text)) OR ((tsv @@ to_tsquery('(uzbekistan)'::text)) AND (body ~~* '%uzbekistan%'::text)) OR ((tsv @@ to_tsquery('(north & korea)'::text)) AND (body ~~* '%north korea%'::text)) OR ((tsv @@ to_tsquery('(taiwan)'::text)) AND (body ~~* '%taiwan%'::text)) OR ((tsv @@ to_tsquery('(australia)'::text)) AND (body ~~* '%australia%'::text))))
Total runtime: 3804.746 ms