Postgresql错误的查询计划与一些参数

时间:2017-08-10 12:08:03

标签: postgresql performance sql-execution-plan query-analyzer

我在一张大表上查询,持续时间从2秒到3分钟,具体取决于参数。有没有办法告诉Postgres(9.6)其查询计划有时非常糟糕?

说明

我有两张桌子:

      Table "public.ItemUpdates"
  Column    |            Type             | Modifiers 
------------+-----------------------------+----------
item_id     | integer                     | not null
type        | integer                     | not null
next_update | timestamp without time zone | not null
Indexes:
    "item_updates_item_id_unique" UNIQUE CONSTRAINT, btree (item_id)
    "ItemUpdates_type_next_update_idx" btree (type, next_update)
Foreign-key constraints:
    "fk_itemupdates_item_id" FOREIGN KEY (item_id) REFERENCES "ItemInfo"(id)

        Table "public.ItemInfo"
     Column     |      Type       |   Modifiers                      
----------------+-----------------+-----------------
id              | integer         | not null default nextval('items_id_seq'::regclass)
status          | smallint        | not null
...
and 10 more columns with text and ts_vectors (74 GB without indexes)

4 ItemUpdates.types :1,2,3和4,重新分区为:

SELECT type, count(*) FROM "ItemUpdates" GROUP BY type

 type |  count
------+----------
    1 |  1859706
    2 |  5061595
    3 | 61973086
    4 |  2018415

我使用的查询是:

SELECT iu.item_id
FROM "ItemUpdates" iu
INNER JOIN "ItemInfo" i ON i.id = iu.item_id
WHERE iu.type = $1
AND iu.next_update < now()
AND i.status = 1
LIMIT 200000

对于类型 1 3 4 ,查询足够快(少于3秒)。 问题是当我查询类型 2 :大约4分钟。

查询计划因类型而异。

1和4 (2,000,000项):

QUERY PLAN                                                                               
 Limit  (cost=28410.75..1679381.70 rows=200000 width=4) (actual time=88.930..2696.893 rows=35 loops=1)
   ->  Nested Loop  (cost=28410.75..8170462.90 rows=986335 width=4) (actual time=88.929..2696.860 rows=35 loops=1)
         ->  Bitmap Heap Scan on "ItemUpdates" iu  (cost=28410.18..459949.42 rows=993328 width=4) (actual time=79.411..2266.702 rows=78312 loops=1)
               Recheck Cond: ((type = 1) AND (next_update < now()))
               Rows Removed by Index Recheck: 14458426
               Heap Blocks: exact=30028 lossy=80441
               ->  Bitmap Index Scan on "ItemUpdates_type_next_update_idx"  (cost=0.00..28161.85 rows=993328 width=0) (actual time=73.388..73.388 rows=262838 loops=1)
                     Index Cond: ((type = 1) AND (next_update < now()))
         ->  Index Scan using "Items_pkey" on "ItemInfo" i  (cost=0.57..7.75 rows=1 width=4) (actual time=0.005..0.005 rows=0 loops=78312)
               Index Cond: (id = iu.item_id)
               Filter: (status = 1)
               Rows Removed by Filter: 1
 Planning time: 0.316 ms
 Execution time: 2696.948 ms

3 (62,000,000件):

 QUERY PLAN                                                                 
 Limit  (cost=0.57..1481409.86 rows=200000 width=4) (actual time=0.202..27676.311 rows=200000 loops=1)
   ->  Nested Loop  (cost=0.57..244077225.62 rows=32952031 width=4) (actual time=0.201..27600.918 rows=200000 loops=1)
         ->  Seq Scan on "ItemUpdates" iu  (cost=0.00..1729530.37 rows=33185659 width=4) (actual time=0.015..237.416 rows=200123 loops=1)
               Filter: ((type = 3) AND (next_update < now()))
               Rows Removed by Filter: 205436
         ->  Index Scan using "Items_pkey" on "ItemInfo" i  (cost=0.57..7.29 rows=1 width=4) (actual time=0.135..0.136 rows=1 loops=200123)
               Index Cond: (id = iu.item_id)
               Filter: (status = 1)
               Rows Removed by Filter: 0
 Planning time: 0.352 ms
 Execution time: 27716.495 ms

它的使用时间更长但仍然可以。

类型 2 (5,000,000项):

QUERY PLAN                                                                                   
Limit  (cost=583733.44..1446607.01 rows=200000 width=4) (actual time=47634.435..130378.407 rows=461 loops=1)
  ->  Hash Join  (cost=583733.44..12198399.97 rows=2692090 width=4) (actual time=47634.434..130378.148 rows=461 loops=1)
        Hash Cond: (i.id = iu.item_id)
        ->  Seq Scan on "ItemInfo" i  (cost=0.00..10591334.10 rows=70216021 width=4) (actual time=0.007..99254.593 rows=70607997 loops=1)
              Filter: (status = 1)
              Rows Removed by Filter: 497449
        ->  Hash  (cost=539252.73..539252.73 rows=2711177 width=4) (actual time=3723.732..3723.732 rows=262938 loops=1)
              Buckets: 131072  Batches: 64  Memory Usage: 1170kB
              ->  Bitmap Heap Scan on "ItemUpdates" iu  (cost=77558.13..539252.73 rows=2711177 width=4) (actual time=147.440..3642.451 rows=262938 loops=1)
                    Recheck Cond: ((type = 2) AND (next_update < now()))
                    Rows Removed by Index Recheck: 9698516
                    Heap Blocks: exact=36509 lossy=54070
                    ->  Bitmap Index Scan on "ItemUpdates_type_next_update_idx"  (cost=0.00..76880.34 rows=2711177 width=0) (actual time=140.141..140.141 rows=358860 loops=1)
                          Index Cond: ((type = 2) AND (next_update < now()))
Planning time: 0.264 ms
Execution time: 130378.583 ms

74 GB表上的Seq Scan非常长,需要大量资源。

表是AUTOVACUUMed,VACUUM ANALYZE没有任何改变。

要恢复:

  • 要解析的2M行=&gt;行
  • 要解析的5M行=&gt;不行。
  • 要解析的62M行=&gt;行

有没有办法让皮条客,强迫或破解查询计划?

0 个答案:

没有答案