摘要:在Postgres 9.3.15上,我的開發和生產計算機上的相同查詢與生產計算機的查詢計劃相差300倍!Postgresql在不同服務器上的不同查詢計劃
我意識到「限制」和「偏移量」在Postgresql中並不是很好,但這並不能解釋爲什麼它在我的開發中速度很快並且生產速度很慢。
有什麼建議嗎?我試着改變cpu_tuple_cost(0.1〜0.5 - 沒有幫助)
我的生產服務器(天青:4個CPU,RAM 16gig)需要1100毫秒來運行此查詢:
prod=# SELECT "designs".* FROM "designs" WHERE "designs"."user_id" IN (SELECT "users"."id" FROM "users" WHERE (code_id=393)) ORDER BY updated_at desc, "designs"."updated_at" DESC LIMIT 20 OFFSET 0;
Time: 1175.486 ms
同時我dev服務器(Virtualbox,laptop,2 gig ram)需要4ms才能在同一個數據庫上運行相同的查詢。
dev=# SELECT "designs".* FROM "designs" WHERE "designs"."user_id" IN (SELECT "users"."id" FROM "users" WHERE (code_id=393)) ORDER BY updated_at desc, "designs"."updated_at" DESC LIMIT 20 OFFSET 0;
Time: 4.249 ms
生產的查詢計劃是這樣的:
prod=# explain SELECT "designs".* FROM "designs" WHERE "designs"."user_id" IN (SELECT "users"."id" FROM "users" WHERE (code_id=393)) ORDER BY updated_at desc, "designs"."updated_at" DESC LIMIT 20 OFFSET 0;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
Limit (cost=169.00..113691.20 rows=20 width=966)
-> Nested Loop Semi Join (cost=169.00..51045428.02 rows=8993 width=966)
-> Index Scan Backward using design_modification_date_idx on designs (cost=85.00..1510927.32 rows=538151 width=966)
-> Index Scan using "User_UserUID_key" on users (cost=84.00..92.05 rows=1 width=4)
Index Cond: (id = designs.user_id)
Filter: (code_id = 393)
(6 rows)
Time: 1.165 ms
dev的查詢計劃是這樣的:
dev=# explain SELECT "designs".* FROM "designs" WHERE "designs"."user_id" IN (SELECT "users"."id" FROM "users" WHERE (code_id=393)) ORDER BY updated_at desc, "designs"."updated_at" DESC LIMIT 20 OFFSET 0;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------
Limit (cost=5686.78..5686.83 rows=20 width=964)
-> Sort (cost=5686.78..5689.41 rows=1052 width=964)
Sort Key: designs.updated_at
-> Nested Loop (cost=0.71..5658.79 rows=1052 width=964)
-> Index Scan using code_idx on users (cost=0.29..192.63 rows=67 width=4)
Index Cond: (code_id = 393)
-> Index Scan using "Design_idx_owneruid" on designs (cost=0.42..73.58 rows=16 width=964)
Index Cond: (user_id = users.id)
(8 rows)
Time: 0.736 ms
編輯:確定傾銷生產數據的全新副本後,我發現查詢規劃器是相同的(所以這是一個數據問題 - 對不起!)。查詢仍然很慢,但有什麼想法可以做些改進呢?我已經嘗試添加上設計(的updated_at,USER_ID)和用戶(ID,code_id)指標無濟於事
輸出解釋(分析一下,緩衝區):
Limit (cost=0.72..10390.79 rows=20 width=962) (actual time=1485.810..22025.828 rows=20 loops=1)
Buffers: shared hit=883264 read=164340
-> Nested Loop Semi Join (cost=0.72..4928529.42 rows=9487 width=962) (actual time=1485.809..22025.809 rows=20 loops=1)
Buffers: shared hit=883264 read=164340
-> Index Scan Backward using design_modification_date_idx on designs (cost=0.42..1442771.50 rows=538270 width=962) (actual time=1.737..18444.598 rows=263043 loops=1)
Buffers: shared hit=108266 read=149409
-> Index Scan using "User_UserUID_key" on users (cost=0.29..6.48 rows=1 width=4) (actual time=0.012..0.012 rows=0 loops=263043)
Index Cond: (id = designs.user_id)
Filter: (code_id = 393)
Rows Removed by Filter: 1
Buffers: shared hit=774998 read=14931
Total runtime: 22027.477 ms
(12 rows)
編輯:對建議查詢的附加說明
dev=# explain (analyze) SELECT designs.*
FROM designs
JOIN (SELECT *
FROM users
WHERE code_id=393
OFFSET 0
) users
ON designs.user_id = users.id
ORDER BY updated_at desc
LIMIT 20;
Limit (cost=0.72..13326.65 rows=20 width=962) (actual time=2597.877..95734.152 rows=20 loops=1)
-> Nested Loop (cost=0.72..6321154.70 rows=9487 width=962) (actual time=2597.877..95734.135 rows=20 loops=1)
Join Filter: (designs.user_id = users.id)
Rows Removed by Join Filter: 143621402
-> Index Scan Backward using design_modification_date_idx on designs (cost=0.42..1410571.52 rows=538270 width=962) (actual time=0.024..5217.228 rows=263043 loops=1)
-> Materialize (cost=0.29..1562.31 rows=608 width=4) (actual time=0.000..0.146 rows=546 loops=263043)
-> Subquery Scan on users (cost=0.29..1559.27 rows=608 width=4) (actual time=0.021..1.516 rows=546 loops=1)
-> Index Scan using code_idx on users users_1 (cost=0.29..1553.19 rows=608 width=602) (actual time=0.020..1.252 rows=546 loops=1)
Index Cond: (code_id = 393)
Total runtime: 95734.353 ms
(10 rows)
請發佈'EXPLAIN(ANALYZE,BUFFERS)'輸出。它看起來像數據庫包含不同的數據。 –
你是對的 - 開發者的數據只是過時了幾天,但是將新的生產副本放到開發中導致了相同的緩慢。 我試着按照下面的@ chris-travers添加索引,但沒有運氣。 我已經將EXPLAIN(ANALYZE,BUFFERS)的輸出添加到主帖子的底部。 –