性能 postgresql 9.1.9/9.3.6 与 9.4.1
Posted
技术标签:
【中文标题】性能 postgresql 9.1.9/9.3.6 与 9.4.1【英文标题】:Perfomance postgresql 9.1.9/9.3.6 vs 9.4.1 【发布时间】:2015-03-15 10:00:04 【问题描述】:我正在比较 9.1.9/9.3.6 和 9.4.1。我认为 9.4.1 的性能应该更好,或者至少不会更差。 但我这里有个问题。 我已经在同一台机器上安装了两个数据库,恢复了相同的转储,使用了 ANALYZE 并且我有 2 个结果,我看到由于某种原因 9.1.9 工作得更快 - 118ms 对 452ms。 我使用 EXPLAIN ANALYZE 检查了相同的 sql 查询(具有相同的 work_mem =8MB 和 shared_buffers = 128MB)。
1) 9.1.9
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=6929.93..6929.94 rows=1 width=10) (actual time=99.175..99.178 rows=25 loops=1)
-> Sort (cost=6929.93..6929.94 rows=1 width=10) (actual time=99.175..99.175 rows=25 loops=1)
Sort Key: (CASE WHEN (p.f_without_price = 1) THEN 0::double precision ELSE p1.price END)
Sort Method: top-N heapsort Memory: 26kB
-> Nested Loop Anti Join (cost=133.65..6929.92 rows=1 width=10) (actual time=0.345..97.884 rows=4876 loops=1)
Join Filter: ((p2.price < p1.price) OR ((p2.price = p1.price) AND (p2.id < p1.id)))
-> Nested Loop Left Join (cost=90.19..6882.40 rows=1 width=64) (actual time=0.344..64.038 rows=4891 loops=1)
Filter: (((p.f_without_price = 1) OR (p1.price <> 0::double precision)) AND (CASE WHEN (p.f_without_price = 1) THEN 0::double precision ELSE p1.price END <> 0::double precision))
-> Nested Loop Left Join (cost=46.75..6834.91 rows=1 width=48) (actual time=0.344..23.213 rows=4889 loops=1)
Join Filter: (p.f_assignable = 0)
Filter: (((p.f_assignable = 1) AND (pc.product_id IS NOT NULL)) OR ((p.f_assignable = 0) AND (pch.product_id IS NULL)))
-> Nested Loop Left Join (cost=46.75..6822.71 rows=2 width=58) (actual time=0.344..16.257 rows=4907 loops=1)
Join Filter: (p.f_assignable = 1)
-> Nested Loop (cost=46.75..6809.23 rows=2 width=54) (actual time=0.343..8.678 rows=4907 loops=1)
-> Nested Loop (cost=0.00..24.84 rows=1 width=58) (actual time=0.017..0.052 rows=2 loops=1)
-> Nested Loop (cost=0.00..16.55 rows=1 width=54) (actual time=0.013..0.035 rows=3 loops=1)
Join Filter: (cs.supplier_id = grps.supplier_id)
-> Index Scan using cs_aggregated_groups_pkey on cs_aggregated_groups grps (cost=0.00..8.27 rows=1 width=50) (actual time=0.006..0.008 rows=3 loops=1)
Index Cond: (customer_id = 1388)
-> Index Scan using index_15 on cs_groups cs (cost=0.00..8.27 rows=1 width=8) (actual time=0.004..0.007 rows=3 loops=3)
Index Cond: (customer_id = 1388)
Filter: (f_primary_group = 1)
-> Index Scan using index_26 on supplier s (cost=0.00..8.27 rows=1 width=4) (actual time=0.004..0.004 rows=1 loops=3)
Index Cond: (id = cs.supplier_id)
Filter: ((f_active = 1) AND (f_deleted = 0))
-> Bitmap Heap Scan on product p (cost=46.75..6754.19 rows=2416 width=12) (actual time=0.401..3.683 rows=2454 loops=2)
Recheck Cond: (supplier_id = s.id)
Filter: ((f_available = 1) AND (f_active = 1) AND (f_deleted = 0) AND ((f_assignable = 1) OR (f_assignable = 0)))
-> Bitmap Index Scan on index_57 (cost=0.00..46.41 rows=2416 width=0) (actual time=0.320..0.320 rows=3550 loops=2)
Index Cond: (supplier_id = s.id)
-> Index Scan using index_49 on product_customer pc (cost=0.00..6.72 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4907)
Index Cond: ((product_id = p.id) AND (customer_id = 1388) AND (customer_id = cs.customer_id))
-> Index Scan using index_63 on product_customer_hidden pch (cost=0.00..6.08 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4907)
Index Cond: ((product_id = p.id) AND (customer_id = 1388) AND (customer_id = cs.customer_id))
-> Bitmap Heap Scan on price p1 (cost=43.44..47.46 rows=1 width=27) (actual time=0.007..0.007 rows=1 loops=4889)
Recheck Cond: ((product_id = p.id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = 1))
Filter: (f_valid = 1)
-> Bitmap Index Scan on price_product_id_group_id_amount_type_id_valid_from_valid_t_key (cost=0.00..43.44 rows=1 width=0) (actual time=0.006..0.006 rows=1 loops=4889)
Index Cond: ((product_id = p.id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = 1))
-> Bitmap Heap Scan on price p2 (cost=43.47..47.48 rows=1 width=27) (actual time=0.006..0.006 rows=1 loops=4891)
Recheck Cond: ((product_id = p1.product_id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = 1) AND (amount = p1.amount))
Filter: (f_valid = 1)
-> Bitmap Index Scan on price_product_id_group_id_amount_type_id_valid_from_valid_t_key (cost=0.00..43.47 rows=1 width=0) (actual time=0.005..0.005 rows=1 loops=4891)
Index Cond: ((product_id = p1.product_id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = 1) AND (amount = p1.amount))
Total runtime: 99.297 ms
(45 rows)
2) 9.4.1
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=503.71..503.72 rows=1 width=10) (actual time=416.762..416.764 rows=25 loops=1)
-> Sort (cost=503.71..503.72 rows=1 width=10) (actual time=416.734..416.734 rows=25 loops=1)
Sort Key: (CASE WHEN (p.f_without_price = 1) THEN 0::double precision ELSE p1.price END)
Sort Method: top-N heapsort Memory: 26kB
-> Nested Loop Anti Join (cost=37.73..503.70 rows=1 width=10) (actual time=0.736..415.337 rows=4876 loops=1)
-> Nested Loop Left Join (cost=37.16..497.90 rows=1 width=64) (actual time=0.697..379.099 rows=4891 loops=1)
Join Filter: ((p1.group_id)::text = ANY ((grps.grp_ids)::text[]))
Rows Removed by Join Filter: 485609
Filter: (((p.f_without_price = 1) OR (p1.price <> 0::double precision)) AND (CASE WHEN (p.f_without_price = 1) THEN 0::double precision ELSE p1.price END <> 0::double precision))
Rows Removed by Filter: 13
-> Nested Loop Left Join (cost=36.61..487.14 rows=1 width=48) (actual time=0.619..24.466 rows=4889 loops=1)
Join Filter: ((p.f_assignable = 0) AND (pch.customer_id = cs.customer_id))
Filter: (((p.f_assignable = 1) AND (pc.product_id IS NOT NULL)) OR ((p.f_assignable = 0) AND (pch.product_id IS NULL)))
Rows Removed by Filter: 18
-> Nested Loop Left Join (cost=36.33..486.50 rows=2 width=58) (actual time=0.595..17.019 rows=4907 loops=1)
Join Filter: ((p.f_assignable = 1) AND (pc.customer_id = cs.customer_id))
-> Nested Loop (cost=36.03..485.82 rows=2 width=54) (actual time=0.573..8.876 rows=4907 loops=1)
-> Nested Loop (cost=0.71..18.42 rows=1 width=58) (actual time=0.101..0.122 rows=2 loops=1)
-> Nested Loop (cost=0.43..16.49 rows=1 width=12) (actual time=0.078..0.091 rows=2 loops=1)
-> Index Scan using index_15 on cs_groups cs (cost=0.28..8.30 rows=1 width=8) (actual time=0.020..0.024 rows=3 loops=1)
Index Cond: (customer_id = 1388)
Filter: (f_primary_group = 1)
-> Index Scan using index_26 on supplier s (cost=0.15..8.17 rows=1 width=4) (actual time=0.006..0.007 rows=1 loops=3)
Index Cond: (id = cs.supplier_id)
Filter: ((f_active = 1) AND (f_deleted = 0))
Rows Removed by Filter: 0
-> Index Scan using cs_aggregated_groups_pkey on cs_aggregated_groups grps (cost=0.28..1.92 rows=1 width=50) (actual time=0.004..0.005 rows=1 loops=2)
Index Cond: ((customer_id = 1388) AND (supplier_id = s.id))
-> Bitmap Heap Scan on product p (cost=35.32..454.81 rows=1259 width=12) (actual time=0.456..3.332 rows=2454 loops=2)
Recheck Cond: (supplier_id = s.id)
Filter: ((f_available = 1) AND (f_active = 1) AND (f_deleted = 0))
Rows Removed by Filter: 1096
Heap Blocks: exact=2866
-> Bitmap Index Scan on index_57 (cost=0.00..35.01 rows=2274 width=0) (actual time=0.300..0.300 rows=3550 loops=2)
Index Cond: (supplier_id = s.id)
-> Index Only Scan using index_49 on product_customer pc (cost=0.29..0.33 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4907)
Index Cond: ((product_id = p.id) AND (customer_id = 1388))
Heap Fetches: 0
-> Index Only Scan using index_63 on product_customer_hidden pch (cost=0.28..0.30 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4907)
Index Cond: ((product_id = p.id) AND (customer_id = 1388))
Heap Fetches: 0
-> Index Scan using price_product_id_group_id_amount_type_id_valid_from_valid_t_key on price p1 (cost=0.56..5.36 rows=166 width=27) (actual time=0.006..0.056 rows=100 loops=4889)
Index Cond: ((product_id = p.id) AND (amount = 1))
Filter: (f_valid = 1)
Rows Removed by Filter: 0
-> Index Scan using price_product_id_group_id_amount_type_id_valid_from_valid_t_key on price p2 (cost=0.56..5.79 rows=1 width=27) (actual time=0.006..0.006 rows=0 loops=4891)
Index Cond: ((product_id = p1.product_id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = p1.amount) AND (amount = 1))
Filter: ((f_valid = 1) AND ((price < p1.price) OR ((price = p1.price) AND (id < p1.id))))
Rows Removed by Filter: 1
Planning time: 2.975 ms
Execution time: 416.935 ms
(51 rows)
3) 9.3.6
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=5705.15..5705.16 rows=1 width=10) (actual time=101.671..101.674 rows=25 loops=1)
-> Sort (cost=5705.15..5705.16 rows=1 width=10) (actual time=101.667..101.669 rows=25 loops=1)
Sort Key: (CASE WHEN (p.f_without_price = 1) THEN 0::double precision ELSE p1.price END)
Sort Method: top-N heapsort Memory: 26kB
-> Nested Loop Anti Join (cost=42.85..5705.14 rows=1 width=10) (actual time=0.505..100.493 rows=4876 loops=1)
-> Nested Loop Left Join (cost=42.29..5662.50 rows=1 width=64) (actual time=0.502..68.448 rows=4891 loops=1)
Filter: (((p.f_without_price = 1) OR (p1.price <> 0::double precision)) AND (CASE WHEN (p.f_without_price = 1) THEN 0::double precision ELSE p1.price END <> 0::double precision))
Rows Removed by Filter: 13
-> Nested Loop Left Join (cost=41.72..5612.79 rows=1 width=48) (actual time=0.499..26.178 rows=4889 loops=1)
Join Filter: ((p.f_assignable = 0) AND (pch.customer_id = cs.customer_id))
Filter: (((p.f_assignable = 1) AND (pc.product_id IS NOT NULL)) OR ((p.f_assignable = 0) AND (pch.product_id IS NULL)))
Rows Removed by Filter: 18
-> Nested Loop Left Join (cost=41.44..5600.55 rows=2 width=58) (actual time=0.497..19.018 rows=4907 loops=1)
Join Filter: ((p.f_assignable = 1) AND (pc.customer_id = cs.customer_id))
-> Nested Loop (cost=41.15..5587.11 rows=2 width=54) (actual time=0.495..11.064 rows=4907 loops=1)
-> Nested Loop (cost=0.71..23.07 rows=1 width=58) (actual time=0.024..0.049 rows=2 loops=1)
-> Nested Loop (cost=0.43..16.49 rows=1 width=12) (actual time=0.017..0.035 rows=2 loops=1)
-> Index Scan using index_15 on cs_groups cs (cost=0.28..8.30 rows=1 width=8) (actual time=0.011..0.016 rows=3 loops=1)
Index Cond: (customer_id = 1388)
Filter: (f_primary_group = 1)
-> Index Scan using index_26 on supplier s (cost=0.15..8.17 rows=1 width=4) (actual time=0.003..0.004 rows=1 loops=3)
Index Cond: (id = cs.supplier_id)
Filter: ((f_active = 1) AND (f_deleted = 0))
Rows Removed by Filter: 0
-> Index Scan using cs_aggregated_groups_pkey on cs_aggregated_groups grps (cost=0.28..6.58 rows=1 width=50) (actual time=0.004..0.005 rows=1 loops=2)
Index Cond: ((customer_id = 1388) AND (supplier_id = s.id))
-> Bitmap Heap Scan on product p (cost=40.44..5551.89 rows=1215 width=12) (actual time=0.471..4.755 rows=2454 loops=2)
Recheck Cond: (supplier_id = s.id)
Filter: ((f_available = 1) AND (f_active = 1) AND (f_deleted = 0) AND ((f_assignable = 1) OR (f_assignable = 0)))
Rows Removed by Filter: 1096
-> Bitmap Index Scan on index_57 (cost=0.00..40.14 rows=2235 width=0) (actual time=0.326..0.326 rows=3550 loops=2)
Index Cond: (supplier_id = s.id)
-> Index Only Scan using index_49 on product_customer pc (cost=0.29..6.70 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4907)
Index Cond: ((product_id = p.id) AND (customer_id = 1388))
Heap Fetches: 0
-> Index Only Scan using index_63 on product_customer_hidden pch (cost=0.28..6.10 rows=1 width=8) (actual time=0.001..0.001 rows=0 loops=4907)
Index Cond: ((product_id = p.id) AND (customer_id = 1388))
Heap Fetches: 0
-> Index Scan using price_product_id_group_id_amount_type_id_valid_from_valid_t_key on price p1 (cost=0.56..49.70 rows=1 width=27) (actual time=0.007..0.007 rows=1 loops=4889)
Index Cond: ((product_id = p.id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = 1))
Filter: (f_valid = 1)
Rows Removed by Filter: 0
-> Index Scan using price_product_id_group_id_amount_type_id_valid_from_valid_t_key on price p2 (cost=0.56..42.63 rows=1 width=27) (actual time=0.005..0.005 rows=0 loops=4891)
Index Cond: ((product_id = p1.product_id) AND ((group_id)::text = ANY ((grps.grp_ids)::text[])) AND (amount = p1.amount) AND (amount = 1))
Filter: ((f_valid = 1) AND ((price < p1.price) OR ((price = p1.price) AND (id < p1.id))))
Rows Removed by Filter: 1
Total runtime: 101.835 ms
(47 rows)
当然,也许 sql-query 不太好,但我想了解为什么 9.4.1 需要更多时间 x4! 你能帮我做什么吗?
UPD。我安装了 9.3.6 并尝试了相同的查询。结果比 9.4.1 好很多。
【问题讨论】:
请发布整个查询和整个解释。 你删除的导入信息最多:查询计划...... 如果计划太长,请将两个计划发布到explain.depesz.com 并在此处放置链接。没有计划就不可能有效地回答这个问题。 对不起,我已经添加了整个解释。查询要长得多,也足够复杂... 【参考方案1】:按照@CraigRinger 的建议,我将两者都放入了explain.depesz.com 并并排查看了它们。 slow 9.4 query 和 fast 9.1 query。
计划基本相同,但有两点很突出。第 4 步,即嵌套循环左连接,在 9.4 中比在 9.1 中花费的时间要长得多。两者似乎有区别,9.4的join多了一个过滤器,Join Filter: ((p1.group_id)::text = ANY ((grps.grp_ids)::text[]))
。这可能表明两个查询之间存在差异。
然后一切都是一样的,直到第 17 步,9.4 的一切都变成梨形。它对价格表进行一次索引扫描,耗时 273 秒。相反,9.1 进行了一系列更有效的位图扫描。同样,有迹象表明查询可能不同。
我会...
确认您正在运行相同的查询 两个版本的表具有相同的索引 尤其是在价格表上 运行几次查询以确保您不只是对磁盘缓存进行基准测试没有看到查询或架构,我无能为力。
【讨论】:
我在所有这些数据库上恢复了相同的转储。我检查了查询中的所有表在所有数据库中是否具有相同的索引。我在每个数据库上运行了几次查询。顺便说一句,我已经安装了 9.3.6 并尝试过 - 它的工作原理与 9.1.9 几乎相同,我在帖子中添加了查询计划。 @Alexander:你恢复转储后analyze
你的桌子了吗?
@a_horse_with_no_name:是的,我做到了。我尝试了 ANALYZE 和 VACUUM ANALYZE 几次,之后又运行了几次查询。
可能是 9.4.1。对错误优化过于敏感,如果我想使用它我必须首先尝试优化查询...以上是关于性能 postgresql 9.1.9/9.3.6 与 9.4.1的主要内容,如果未能解决你的问题,请参考以下文章