我在一张大表上查询,持续时间从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没有任何改变。
要恢复:
有没有办法让皮条客,强迫或破解查询计划?