为什么'WHERE col = int'使这个PostgreSQL查询变慢?

时间:2014-11-30 16:10:55

标签: sql query-optimization postgresql-9.1 postgresql-performance

我正在进行全文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

0 个答案:

没有答案