当我添加ORDER BY
时,我的查询执行时间会爆炸,我似乎无法得到它背后的推理。我认为在索引字段上订购应该很简单。
所以两个查询看起来像这样:
这个需要30-50秒:
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
SELECT * FROM "content_entry"
INNER JOIN "marketplace_review" ON ("content_entry"."id" = "marketplace_review"."entry_ptr_id")
INNER JOIN "marketplace_product" ON ("marketplace_review"."product_id" = "marketplace_product"."id")
WHERE ("content_entry"."type" = 3 AND "marketplace_product"."brand_id" = 750)
ORDER BY "content_entry"."timestamp" DESC
LIMIT 3
这个不到一秒钟
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
SELECT * FROM "content_entry"
INNER JOIN "marketplace_review" ON ("content_entry"."id" = "marketplace_review"."entry_ptr_id")
INNER JOIN "marketplace_product" ON ("marketplace_review"."product_id" = "marketplace_product"."id")
WHERE ("content_entry"."type" = 3 AND "marketplace_product"."brand_id" = 750)
LIMIT 3
订单的输出:
[
{
"Plan": {
"Node Type": "Limit",
"Parallel Aware": false,
"Startup Cost": 1.43,
"Total Cost": 98242.01,
"Plan Rows": 3,
"Plan Width": 385,
"Actual Startup Time": 2668.251,
"Actual Total Time": 45068.099,
"Actual Rows": 3,
"Actual Loops": 1,
"Output": [""],
"Shared Hit Blocks": 60929421,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Join Type": "Inner",
"Startup Cost": 1.43,
"Total Cost": 29046467.49,
"Plan Rows": 887,
"Plan Width": 385,
"Actual Startup Time": 2668.250,
"Actual Total Time": 45068.095,
"Actual Rows": 3,
"Actual Loops": 1,
"Output": [""],
"Shared Hit Blocks": 60929421,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Join Type": "Inner",
"Startup Cost": 1.00,
"Total Cost": 18561128.82,
"Plan Rows": 17657640,
"Plan Width": 389,
"Actual Startup Time": 0.036,
"Actual Total Time": 23010.813,
"Actual Rows": 5636983,
"Actual Loops": 1,
"Output": [""],
"Shared Hit Blocks": 29168382,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Index Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Scan Direction": "Backward",
"Index Name": "content_entry_d7e6d55b",
"Relation Name": "content_entry",
"Schema": "public",
"Alias": "content_entry",
"Startup Cost": 0.56,
"Total Cost": 5903549.69,
"Plan Rows": 24176239,
"Plan Width": 385,
"Actual Startup Time": 0.031,
"Actual Total Time": 5038.896,
"Actual Rows": 5636983,
"Actual Loops": 1,
"Output": [""],
"Filter": "(content_entry.type = 3)",
"Rows Removed by Filter": 1872638,
"Shared Hit Blocks": 6559529,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Scan Direction": "Forward",
"Index Name": "marketplace_review_pkey",
"Relation Name": "marketplace_review",
"Schema": "public",
"Alias": "marketplace_review",
"Startup Cost": 0.44,
"Total Cost": 0.51,
"Plan Rows": 1,
"Plan Width": 8,
"Actual Startup Time": 0.002,
"Actual Total Time": 0.002,
"Actual Rows": 1,
"Actual Loops": 5636983,
"Output": [""],
"Index Cond": "(marketplace_review.entry_ptr_id = content_entry.id)",
"Rows Removed by Index Recheck": 0,
"Shared Hit Blocks": 22608853,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
}
]
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Scan Direction": "Forward",
"Index Name": "marketplace_product_pkey",
"Relation Name": "marketplace_product",
"Schema": "public",
"Alias": "marketplace_product",
"Startup Cost": 0.43,
"Total Cost": 0.58,
"Plan Rows": 1,
"Plan Width": 4,
"Actual Startup Time": 0.003,
"Actual Total Time": 0.003,
"Actual Rows": 0,
"Actual Loops": 5636983,
"Output": ["marketplace_product.id"],
"Index Cond": "(marketplace_product.id = marketplace_review.product_id)",
"Rows Removed by Index Recheck": 0,
"Filter": "(marketplace_product.brand_id = 750)",
"Rows Removed by Filter": 1,
"Shared Hit Blocks": 31761039,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
}
]
}
]
},
"Planning Time": 1.493,
"Triggers": [
],
"Execution Time": 45068.146
}
]
没有订单的那个输出:
[
{
"Plan": {
"Node Type": "Limit",
"Parallel Aware": false,
"Startup Cost": 24.64,
"Total Cost": 1780.29,
"Plan Rows": 3,
"Plan Width": 1412,
"Actual Startup Time": 0.039,
"Actual Total Time": 0.060,
"Actual Rows": 3,
"Actual Loops": 1,
"Output": [""],
"Shared Hit Blocks": 25,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Join Type": "Inner",
"Startup Cost": 24.64,
"Total Cost": 527304.93,
"Plan Rows": 901,
"Plan Width": 1412,
"Actual Startup Time": 0.038,
"Actual Total Time": 0.059,
"Actual Rows": 3,
"Actual Loops": 1,
"Output": [""],
"Shared Hit Blocks": 25,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Join Type": "Inner",
"Startup Cost": 24.08,
"Total Cost": 526285.64,
"Plan Rows": 1249,
"Plan Width": 1027,
"Actual Startup Time": 0.028,
"Actual Total Time": 0.033,
"Actual Rows": 3,
"Actual Loops": 1,
"Output": [""],
"Shared Hit Blocks": 10,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Index Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Scan Direction": "Forward",
"Index Name": "marketplace_product_521b20f5",
"Relation Name": "marketplace_product",
"Schema": "public",
"Alias": "marketplace_product",
"Startup Cost": 0.43,
"Total Cost": 761.18,
"Plan Rows": 189,
"Plan Width": 986,
"Actual Startup Time": 0.010,
"Actual Total Time": 0.010,
"Actual Rows": 1,
"Actual Loops": 1,
"Output": [""],
"Index Cond": "(marketplace_product.brand_id = 750)",
"Rows Removed by Index Recheck": 0,
"Shared Hit Blocks": 4,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
},
{
"Node Type": "Bitmap Heap Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Relation Name": "marketplace_review",
"Schema": "public",
"Alias": "marketplace_review",
"Startup Cost": 23.65,
"Total Cost": 2771.16,
"Plan Rows": 939,
"Plan Width": 41,
"Actual Startup Time": 0.013,
"Actual Total Time": 0.017,
"Actual Rows": 3,
"Actual Loops": 1,
"Output": [""],
"Recheck Cond": "(marketplace_review.product_id = marketplace_product.id)",
"Rows Removed by Index Recheck": 0,
"Exact Heap Blocks": 3,
"Lossy Heap Blocks": 0,
"Shared Hit Blocks": 6,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0,
"Plans": [
{
"Node Type": "Bitmap Index Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Index Name": "marketplace_review_product_id_4e8c6bab491b1730_idx",
"Startup Cost": 0.00,
"Total Cost": 23.42,
"Plan Rows": 939,
"Plan Width": 0,
"Actual Startup Time": 0.009,
"Actual Total Time": 0.009,
"Actual Rows": 13,
"Actual Loops": 1,
"Index Cond": "(marketplace_review.product_id = marketplace_product.id)",
"Shared Hit Blocks": 3,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
}
]
}
]
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Scan Direction": "Forward",
"Index Name": "content_entry_pkey",
"Relation Name": "content_entry",
"Schema": "public",
"Alias": "content_entry",
"Startup Cost": 0.56,
"Total Cost": 0.81,
"Plan Rows": 1,
"Plan Width": 385,
"Actual Startup Time": 0.006,
"Actual Total Time": 0.006,
"Actual Rows": 1,
"Actual Loops": 3,
"Output": [""],
"Index Cond": "(content_entry.id = marketplace_review.entry_ptr_id)",
"Rows Removed by Index Recheck": 0,
"Filter": "(content_entry.type = 3)",
"Rows Removed by Filter": 0,
"Shared Hit Blocks": 15,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
}
]
}
]
},
"Planning Time": 0.771,
"Triggers": [
],
"Execution Time": 0.182
}
]
只是没有连接的排序再次低于1秒,这是正常的,因为有序字段被索引,所以我不明白为什么连接会破坏那么多的排序。
答案 0 :(得分:3)
您的查询减少了噪音:
org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets
使用SELECT *
FROM content_entry ce
JOIN marketplace_review mr ON mr.entry_ptr_id = ce.id
JOIN marketplace_product mp ON mp.id = mr.product_id
WHERE ce.type = 3
AND mp.brand_id = 750
ORDER BY ce.timestamp DESC -- adding this makes it slow
LIMIT 3
而不是LIMIT 3
的查询可以自由返回符合条件的任意三行。这是你的第一个快速查询。
添加ORDER BY
后,Postgres必须考虑所有符合条件的行,对它们进行排序并根据您的ORDER BY
表达式识别“first”3。如果明显更多的行符合ORDER BY
中的三个,那么这实际上要贵得多。查询可能必须访问数百万行而不是仅仅手持。这是你的第二个慢查询。
第一个查询获得更快更多行符合条件似乎反直觉,而第二个查询变得更慢。但是,如果你考虑一下,这是有道理的。
如果您的索引完全符合LIMIT 3
条件并且不包含太多不合格的行,则可以显着提高第二个查询的性能 - 而且Postgres也不会期望太多不符合条件的行基于当前统计和成本设置的行。
估计4个谓词(2x WHERE,2x JOIN)的组合选择性并不容易。增加关键列的统计目标可能帮助。
ORDER BY
的(缺失)输出结合可用资源和实际资源设置应该提供线索,其中估计偏离实际计数,其中成本或资源设置可能不合适以及不同索引可能有帮助的地方。
在黑暗中拍摄:
如果您还没有,EXPLAIN (ANALYZE, BUFFERS)
上的多列索引将有助于两个查询。或者,如果您总是查询content_entry(type, timestamp DESC)
(并且这不是大多数行的类型),则部分索引会更有效:
type = 3
相关:
确保列CREATE INDEX foo ON content_entry (timestamp DESC) WHERE entry = 3;
已定义content_entry.timestamp
,或考虑NOT NULL
。相关:
你真的需要从3个表(ORDER BY ce.timestamp DESC NULL LAST
)返回所有列吗?