1

我编写了下面的函数,它与下表结合使用,存储公司的财政月份定义,但是当用于按财政月份聚合数据时,这个函数似乎相当慢。任何人都可以就我如何加快速度提供一些指示吗?

编辑:我仍然有这个功能的一些瓶颈。我已经重写它以去除一些绒毛,但它仍然比在我的查询中加入财政月表要慢得多。但是,为了便于使用,我仍然宁愿使用函数,因此我不必重写仍在使用它的几十个查询。

创建或替换函数 get_fiscal_month(date) 返回整数为 $BODY$ SELECT CASE WHEN EXTRACT(YEAR FROM $1) < 2008 THEN EXTRACT(MONTH FROM $1)::integer ELSE (SELECT month FROM accounting_months WHERE EXTRACT(YEAR FROM $1) = year AND $1 >= start_date AND $1 <= end_date) END $BODY$ LANGUAGE sql VOLATILE COST 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. 删除 CASE WHEN 日期 < 2008(无论如何我在 2008 年之前没有任何数据)
2. 删除 WHERE(从日期提取年份)= 年(这是不必要的步骤)
3. 将 VOLATILE 更改为稳定
4. 更改成本从 100 到 1000

CREATE TABLE 财政月(id 序列不为空,年份整数不为空,月份整数不为空,start_date 日期不为空,结束日期日期不为空,约束财政月_pkey 主键(id),约束财政月_ukey 唯一(年,月))

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
活动元组 86
死元组 0
堆块读取 3047堆 索引块命中 49 块 索引
命中 513262 3251026 Toast Blocks Read Toast Blocks Hit Toast Index Blocks Read Toast Index Blocks Hit Last Vacuum 2014-05-05 16:46:54.087489-05 Last Autovacuum Last Analyze 2014-05-06 13:23:47.709653-05 Last Autoanalyze 2014-05 -05 16:47:29.248862-05









表大小 8192 字节
Toast 表大小 无
索引大小 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”

ps 我正在使用 Postgresql 8.3
ps 我正在使用 Postgresql 8.4

4

2 回答 2

4

该参考表中有哪些数据?会计月份通常可以从一个日期确定而无需查询。

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

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

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

于 2013-11-13T09:33:59.890 回答
0

我编写了下面的函数,它与下表结合使用,存储公司的财政月份定义,但是当用于按财政月份聚合数据时,这个函数似乎相当慢。任何人都可以就我如何加快速度提供一些指示吗?

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

你应该做的是 IMO,只有data >= '2008-01-01'. 将它封装在一个函数中意味着它可能不是可内联的,因此您不能执行哈希连接,而是坚持使用嵌套循环,这几乎肯定是您的问题所在。

于 2013-11-13T08:40:47.177 回答