我有两个简单的查询在中小型表上实际上是相同的,这些查询给出了截然不同的结果,我试图理解为什么。
这是快速的(1秒):
select *
from financials.income f
where f.itemtype in ('SALES') and f.company_id=6445
这是缓慢的(1分钟):
create temp table t_co as select 6445 as company_id;
select f.*
from financials.income f
inner join t_co on f.company_id=t_co.company_id
where f.itemtype in ('SALES')
以下是快速解释分析:
[
{
"Execution Time": 97.271,
"Planning Time": 2.833,
"Plan": {
"Exact Heap Blocks": 29,
"Node Type": "Bitmap Heap Scan",
"Actual Total Time": 96.876,
"Shared Hit Blocks": 14822,
"Plans": [
{
"Node Type": "Bitmap Index Scan",
"Actual Total Time": 76.988,
"Shared Hit Blocks": 14793,
"Shared Read Blocks": 0,
"Local Hit Blocks": 0,
"Local Dirtied Blocks": 0,
"Temp Written Blocks": 0,
"Plan Width": 0,
"Total Cost": 69.98,
"Actual Startup Time": 76.988,
"Temp Read Blocks": 0,
"Local Read Blocks": 0,
"Index Name": "unique_income_daterange",
"Startup Cost": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 956,
"Index Cond": "((company_id = 6445) AND (itemtype = 'SALES'::text))",
"Parallel Aware": false,
"Actual Rows": 1883,
"Parent Relationship": "Outer",
"Actual Loops": 1
}
],
"Shared Read Blocks": 0,
"Relation Name": "income",
"Local Hit Blocks": 0,
"Local Dirtied Blocks": 0,
"Temp Written Blocks": 0,
"Plan Width": 75,
"Actual Loops": 1,
"Rows Removed by Index Recheck": 0,
"Lossy Heap Blocks": 0,
"Alias": "f",
"Recheck Cond": "((company_id = 6445) AND (itemtype = 'SALES'::text))",
"Temp Read Blocks": 0,
"Actual Startup Time": 96.406,
"Local Read Blocks": 0,
"Startup Cost": 70.22,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 956,
"Parallel Aware": false,
"Actual Rows": 1883,
"Total Cost": 3698.02
},
"Triggers": []
}
]
对于缓慢的人:
[
{
"Execution Time": 69825.054,
"Planning Time": 0.166,
"Plan": {
"Node Type": "Hash Join",
"Actual Total Time": 69823.936,
"Shared Hit Blocks": 11135,
"Plans": [
{
"Node Type": "Seq Scan",
"Actual Total Time": 0.007,
"Shared Hit Blocks": 0,
"Shared Read Blocks": 0,
"Relation Name": "t_co",
"Local Hit Blocks": 1,
"Local Dirtied Blocks": 0,
"Temp Written Blocks": 0,
"Plan Width": 4,
"Actual Loops": 1,
"Actual Startup Time": 0.005,
"Alias": "t_co",
"Temp Read Blocks": 0,
"Local Read Blocks": 0,
"Startup Cost": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 2550,
"Parallel Aware": false,
"Actual Rows": 1,
"Parent Relationship": "Outer",
"Total Cost": 35.5
},
{
"Node Type": "Hash",
"Actual Total Time": 69787.311,
"Peak Memory Usage": 3137,
"Shared Hit Blocks": 11135,
"Plans": [
{
"Exact Heap Blocks": 25326,
"Node Type": "Bitmap Heap Scan",
"Actual Total Time": 68990.682,
"Shared Hit Blocks": 11135,
"Plans": [
{
"Node Type": "Bitmap Index Scan",
"Actual Total Time": 52693.721,
"Shared Hit Blocks": 11135,
"Shared Read Blocks": 193938,
"Local Hit Blocks": 0,
"Local Dirtied Blocks": 0,
"Temp Written Blocks": 0,
"Plan Width": 0,
"Total Cost": 107233,
"Actual Startup Time": 52693.721,
"Temp Read Blocks": 0,
"Local Read Blocks": 0,
"Index Name": "unique_income_daterange",
"Startup Cost": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 1565411,
"Index Cond": "(itemtype = 'SALES'::text)",
"Parallel Aware": false,
"Actual Rows": 1519378,
"Parent Relationship": "Outer",
"Actual Loops": 1
}
],
"Shared Read Blocks": 219264,
"Relation Name": "income",
"Local Hit Blocks": 0,
"Local Dirtied Blocks": 0,
"Temp Written Blocks": 0,
"Plan Width": 75,
"Actual Loops": 1,
"Rows Removed by Index Recheck": 0,
"Lossy Heap Blocks": 0,
"Alias": "f",
"Recheck Cond": "(itemtype = 'SALES'::text)",
"Temp Read Blocks": 0,
"Actual Startup Time": 52699.492,
"Local Read Blocks": 0,
"Startup Cost": 107624.35,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 1565411,
"Parallel Aware": false,
"Actual Rows": 1511066,
"Parent Relationship": "Outer",
"Total Cost": 317692.99
}
],
"Shared Read Blocks": 219264,
"Local Hit Blocks": 0,
"Original Hash Batches": 64,
"Local Dirtied Blocks": 0,
"Temp Written Blocks": 19128,
"Plan Width": 75,
"Actual Loops": 1,
"Original Hash Buckets": 65536,
"Hash Batches": 64,
"Actual Startup Time": 69787.311,
"Temp Read Blocks": 0,
"Local Read Blocks": 0,
"Hash Buckets": 65536,
"Startup Cost": 317692.99,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 1565411,
"Parallel Aware": false,
"Actual Rows": 1511066,
"Parent Relationship": "Inner",
"Total Cost": 317692.99
}
],
"Shared Read Blocks": 219264,
"Join Type": "Inner",
"Temp Written Blocks": 19192,
"Local Dirtied Blocks": 0,
"Local Hit Blocks": 1,
"Plan Width": 75,
"Actual Loops": 1,
"Actual Startup Time": 69793.165,
"Hash Cond": "(t_co.company_id = f.company_id)",
"Temp Read Blocks": 355,
"Local Read Blocks": 0,
"Startup Cost": 357134.63,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Written Blocks": 0,
"Plan Rows": 3019514,
"Parallel Aware": false,
"Actual Rows": 1883,
"Total Cost": 605158.39
},
"Triggers": []
}
]
company_id上有一个索引,4列上有一个主键,还有一个约束来确保日期不重叠。慢查询看起来像是遇到一个约束,用于确保日期不重叠,但我不明白为什么因为我只加入一列?
ADD CONSTRAINT unique_income_daterange EXCLUDE USING gist (
validrangez WITH &&,
company_id WITH =,
balancedate WITH =,
itemtype WITH =);
答案 0 :(得分:0)
问题是,对于临时表,没有自动收集表统计信息,因此PostgreSQL会在没有有效统计信息的情况下计划查询并达到错误的计划。
您可以通过运行
来解决这个问题ANALYZE t_co;
在运行查询之前。
wildplasser建议的临时视图的工作原因是,在这种情况下,SELECT 6445
成为SQL查询的一部分,因此优化器有更多信息。请注意,临时视图不指向任何表。