我编写了下面的函数,它与下表结合使用,存储公司的财政月份定义,但是当用于按财政月份聚合数据时,这个函数似乎相当慢。任何人都可以就我如何加快速度提供一些指示吗?
编辑:我仍然有这个功能的一些瓶颈。我已经重写它以去除一些绒毛,但它仍然比在我的查询中加入财政月表要慢得多。但是,为了便于使用,我仍然宁愿使用函数,因此我不必重写仍在使用它的几十个查询。
创建或替换函数 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