Postgresql 需要帮助优化这个简单的查询吗
我的最终目标是使用索引优化查询,但我在添加正确的索引时遇到了问题。我尝试过的所有方法在解释图中的成本都是相同的,并且没有任何迹象表明它甚至使用了任何索引 我有两张桌子:Postgresql 需要帮助优化这个简单的查询吗,postgresql,date,indexing,Postgresql,Date,Indexing,我的最终目标是使用索引优化查询,但我在添加正确的索引时遇到了问题。我尝试过的所有方法在解释图中的成本都是相同的,并且没有任何迹象表明它甚至使用了任何索引 我有两张桌子: 事件有两列日期列:开始日期和结束日期(可以为空) 会计日包括: 两列日期列开始日期和结束日期(不能为空) 会计年度char(4) 会计季度char(1) 还有另一个表address,它只是一对一的,在事件中有一个外键。除了公钥,上面没有索引 我有一个无法更改的查询,它可以计算出事件在哪个会计季度和年份开始: SELECT
有两列事件
列:日期
和开始日期
(可以为空)结束日期
包括:会计日
- 两列
列日期
和开始日期
(不能为空)结束日期
- 会计年度
char(4)
- 会计季度
char(1)
- 两列
address
,它只是一对一的,在事件中有一个外键。除了公钥,上面没有索引
我有一个无法更改的查询,它可以计算出事件在哪个会计季度和年份开始:
SELECT
e.*,
(select 'Q' || fd.fiscal_quarter || ' FY' || fd.fiscal_year
from fiscal_date fd
where e.start_date between fd.start_date and fd.end_date
limit 1) as fiscal_quarter_year,
(select 'Q' || fd.fiscal_quarter
from fiscal_date fd
where e.start_date between fd.start_date and fd.end_date
limit 1) as fiscal_quarter,
(select 'FY' || fd.fiscal_year
from fiscal_date fd
where e.start_date between fd.start_date and fd.end_date
limit 1) as fiscal_year,
a.street1, a.street2, a.street3, a.city, a.state, a.country, a.postal_code
FROM event AS e
LEFT OUTER JOIN address a ON e.address_id=a.address_id;
下面是对查询的解释(请注意左侧所有昂贵的seq扫描):
根据要求,以下是解释分析的输出:
Hash Left Join (cost=115.78..2846.64 rows=1649 width=5087) (actual time=18.334..134.279 rows=1649 loops=1)
Hash Cond: (e.address_id = a.address_id)
-> Seq Scan on event e (cost=0.00..323.49 rows=1649 width=5031) (actual time=0.223..19.808 rows=1649 loops=1)
-> Hash (cost=68.68..68.68 rows=3768 width=60) (actual time=17.797..17.797 rows=3768 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 248kB
-> Seq Scan on address a (cost=0.00..68.68 rows=3768 width=60) (actual time=0.004..9.071 rows=3768 loops=1)
SubPlan 1
-> Limit (cost=0.00..0.49 rows=1 width=28) (actual time=0.011..0.014 rows=1 loops=1649)
-> Seq Scan on fiscal_date fd (cost=0.00..1.46 rows=3 width=28) (actual time=0.006..0.006 rows=1 loops=1649)
Filter: (($0 >= start_date) AND ($0 <= end_date))
SubPlan 2
-> Limit (cost=0.00..0.48 rows=1 width=8) (actual time=0.010..0.012 rows=1 loops=1649)
-> Seq Scan on fiscal_date fd (cost=0.00..1.43 rows=3 width=8) (actual time=0.006..0.006 rows=1 loops=1649)
Filter: (($1 >= start_date) AND ($1 <= end_date))
SubPlan 3
-> Limit (cost=0.00..0.48 rows=1 width=20) (actual time=0.010..0.012 rows=1 loops=1649)
-> Seq Scan on fiscal_date fd (cost=0.00..1.43 rows=3 width=20) (actual time=0.005..0.005 rows=1 loops=1649)
Filter: (($2 >= start_date) AND ($2 <= end_date))
Total runtime: 138.008 ms
Hash Left Join(成本=115.78..2846.64行=1649宽度=5087)(实际时间=18.334..134.279行=1649循环=1)
散列条件:(e.address\u id=a.address\u id)
->事件e上的顺序扫描(成本=0.00..323.49行=1649宽度=5031)(实际时间=0.223..19.808行=1649循环=1)
->散列(成本=68.68..68.68行=3768宽度=60)(实际时间=17.797..17.797行=3768循环=1)
存储桶:1024批:1内存使用率:248kB
->地址a上的顺序扫描(成本=0.00..68.68行=3768宽度=60)(实际时间=0.004..9.071行=3768循环=1)
子计划1
->限制(成本=0.00..0.49行=1宽度=28)(实际时间=0.011..0.014行=1圈=1649)
->财政日fd上的顺序扫描(成本=0.00..1.46行=3宽度=28)(实际时间=0.006..0.006行=1圈=1649)
过滤器:($0>=开始日期)和($0限制(成本=0.00..0.48行=1宽度=8)(实际时间=0.010..0.012行=1循环=1649)
->财政日fd上的顺序扫描(成本=0.00..1.43行=3宽度=8)(实际时间=0.006..0.006行=1圈=1649)
过滤器:($1>=开始日期)和($1限制(成本=0.00..0.48行=1宽度=20)(实际时间=0.010..0.012行=1循环=1649)
->财政日fd上的顺序扫描(成本=0.00..1.43行=3宽度=20)(实际时间=0.005..0.005行=1圈=1649)
筛选器:($2>=start_date)和($2Ok,所以您的问题不在于会计日期顺序扫描,因为行数太少,顺序扫描可能是正确的做法。您可能需要对两个表的地址进行索引。\u id。
如果adress_是adress表的主键,则它已被索引
另外,为了确保,在所有表上运行真空满和真空分析
编辑:
考虑到行数太少,性能似乎很差(10000以下算不了什么)。表真的很大吗?还是硬件很陈旧?如果不是,你可能应该认真看看配置(工作内存等)请发布explain Analysis的输出,从提供的信息中很难得出很多结论。一般提示是尽可能在子查询上使用联接,它通常表现得更好。酷酷的explain,这是什么原因?这意味着什么?有没有遗漏的查询?您显示的查询将从偶数中选择所有行t、 所以索引是没有用的。也许只有我一个人,但我发现explain analyze
的纯文本输出信息更丰富(也更容易理解)而不是图形display@amphetamachine您的查询有问题-您使用的是限制
,而没有排序依据
,因此PostgreSQL可以返回它首先找到的匹配行。@安非他命机器同意它与优化无关。我只是指出了问题。顺便说一句,我对它感到非常厌倦在这些环境中,人们无法更改查询、无法更新PostgreSQL、无法安装任何东西、无法访问Internet,并且需要一个实际上根本不会改变任何东西的神奇修复程序。如果您身处这样的环境,我深表同情。