优化Postgresql函数财务月日期

时间:2013-09-05 15:51:01

标签: sql postgresql sql-function

我编写了以下函数,该函数与下表一起用于存储公司的会计月定义,但是当用于按会计月汇总数据时,此函数似乎相当慢。任何人都可以就如何加快速度提出一些指示吗?

编辑:我仍然遇到这个功能的瓶颈。我已经重写了它以消除一些漏洞,但它仍然比在我的查询中加入fiscal_months表要慢得多。但是我仍然宁愿使用一个易于使用的函数,因此我不必重写几十个仍在使用它的查询。

创建或替换函数get_fiscal_month(date) RETURNS整数AS $ BODY $         选择案例             提取时(年1美元起)< 2008那么提取(月数来自$ 1)::整数             其他                 (选择月份FROM fiscal_months WHERE EXTRACT(年份来自$ 1)=年份和$ 1> = start_date AND $ 1< = end_date)         结束     $ BODY $       LANGUAGE sql VOLATILE       成本100;

编辑:2014年5月6日(重写功能略快)

CREATE OR REPLACE FUNCTION get_fiscal_month(date)
    RETURNS integer AS
    $BODY$
    SELECT month FROM fiscal_months WHERE $1 >= start_date AND $1 <= end_date
    $BODY$
LANGUAGE sql STABLE
COST 1000;

更改
1.删​​除日期为&lt; 2008年(无论如何,我在2008年之前没有任何数据)
2.删除了WHERE(从日期提取年份)=年(这是一个不必要的步骤)
3.将挥发变为稳定
4.将成本从100改为1000

    CREATE TABLE fiscal_months     (       id serial NOT NULL,       年整数NOT NULL,       月整数NOT NULL,       start_date日期NOT NULL,       end_date日期NOT NULL,       CONSTRAINT fiscal_months_pkey PRIMARY KEY(id),       CONSTRAINT fiscal_months_ukey UNIQUE(年,月)     )

CREATE TABLE fiscal_months
(
id serial NOT NULL,
year integer NOT NULL,
month integer NOT NULL,
start_date date NOT NULL,
end_date date NOT NULL,
CONSTRAINT fiscal_months_pkey PRIMARY KEY (id),
CONSTRAINT fiscal_months_ukey UNIQUE (year, month),
CONSTRAINT fiscal_months_ukey_end UNIQUE (end_date),
CONSTRAINT fiscal_months_ukey_start UNIQUE (start_date)
)

CREATE INDEX fiscal_months_index_bothdates
    ON fiscal_months USING btree (start_date, end_date);

CREATE INDEX fiscal_months_index_test2
    ON fiscal_months USING btree (start_date);

更改
1.从SO用户添加以下评论的索引。

表格统计
顺序扫描48018264
顺序元组阅读4006572336
指数扫描3251027 索引元组获取27236663
元组插入0
元组更新0
元组已删除0
元组HOT更新0
Live Tuples 86
死元组0
堆积块阅读3047
堆块命中51266249
索引块阅读13
索引块命中3251026 吐司块读取
Toast Blocks Hit Toast Index Blocks读取
Toast Index Blocks Hit Last Vacuum 2014-05-05 16:46:54.087489-05
最后一次Autovacuum
最后分析2014-05-06 13:23:47.709653-05
最后一次自动分析2014-05-05 16:47:29.248862-05
表大小8192字节
吐司桌面大小无
索引大小96 kB

示例数据
年月Start_Date End_Date
---- ----- ---------- ---------
2014 1“2014-01-01”“2014-01-24”
2014 2“2014-01-25”“2014-02-21”
2014 3“2014-02-22”“2014-03-28”
2014 4“2014-03-29”“2014-04-25”
2014 5“2014-04-26”“2014-05-23”
2014 6“2014-05-24”“2014-06-27”

P.S。我正在使用Postgresql 8.3
附:我正在使用Postgresql 8.4

2 个答案:

答案 0 :(得分:3)

该参考表中有哪些数据?财政月份通常可以从没有求助的日期确定。

例如,如果您的会计年度2012年从2012年4月到2013年3月,则您可以通过以下方式确定当前会计月:

to_char(date_trunc('month',current_date) - interval '3' month, 'YYYY MM')

我会考虑以这种方式实现算法,最好是在SQL中(当然,使用CASE,因为它看起来像2009年的财政月逻辑改变了)。

答案 1 :(得分:0)

  

我已经编写了以下功能,该功能与下表一起用于存储公司的会计月定义,但是当用于按会计月汇总数据时,此功能似乎相当慢。任何人都可以就如何加快速度提出一些指示吗?

我认为您的问题在于如何使用此功能。如果您以这种方式聚合数据,则表示您拒绝计划者加入fiscal_month()。

您应该做什么IMO,只有在 data >= '2008-01-01'时,才会在聚合查询的UNION部分调用fiscal_month()。将它封装在一个函数中意味着它可能不是可内联的,因此不是能够进行散列连接,而是坚持使用嵌套循环,这几乎肯定是你的问题所在。