需要帮助优化这个简单的查询

时间:2014-09-10 19:17:40

标签: postgresql date indexing

我的最终目标是使用索引优化我的查询,但是我在添加正确的索引时遇到了麻烦。我尝试的所有内容都会在Explain图中产生相同的成本,并且没有迹象表明它甚至使用了任何索引。

我有两张桌子:

  • event有两个date列:start_dateend_date(可以为null)。
  • fiscal_date
    • 两个datestart_dateend_date(不能为空)
    • fiscal_year
    • 类型的char(4)
    • fiscal_quarter
    • 类型的char(1)

还有另一个表addressevent中的外键一对一。保存公钥时没有索引。

我有一个查询,我无法更改,以确定事件开始的财政季度和年度

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;

这是查询的EXPLAIN(注意左边所有昂贵的seq扫描):

explain of query

根据要求,这是explain analyze的输出:

 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

我已经尝试将索引添加到event,索引开始日期和结束日期(两者都单独),为fiscal_date的日期列添加索引,但似乎没有什么可以降低成本计算此查询。

如何优化此查询,或者是否可能?

1 个答案:

答案 0 :(得分:0)

好的,所以你的问题不是财务日期顺序扫描,行数很少,顺序扫描可能是正确的事情。您可能希望在两个表上都使用index on address._id。 如果adress_is是地址表的主键,则它已被编入索引。

另外,为了确保,在所有表格上运行真空充分和真空分析。

编辑: 考虑到行数太少(10000以下什么都没有),性能似乎非常糟糕。桌子真的很大还是古老的硬件?如果不是,你应该认真看看配置(工作内存等)