【发布时间】:2013-09-09 13:15:34
【问题描述】:
我编写了下面的函数,它与下表结合使用,存储公司的会计月份定义,但是当用于按会计月份聚合数据时,这个函数似乎相当慢。谁能指点我如何加快速度?
编辑:我仍然有这个功能的一些瓶颈。我已经重写它以消除一些绒毛,但它仍然比在我的查询中加入财政月表要慢得多。但是我还是宁愿使用一个函数来方便使用,这样我就不必重写几十个仍在使用它的查询。
创建或替换函数 get_fiscal_month(date)
返回整数 AS
$身体$
选择案例
当提取(年从 1 美元)= 开始日期和 1 美元
编辑: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. 删除日期为
2. 去掉 WHERE (EXTRACT YEAR FROM date) = year(这是一个不必要的步骤)
3. 将 VOLATILE 更改为 STABLE
4. 成本从100改为1000
创建表财政_月
(
id 序列号 NOT NULL,
年份整数 NOT NULL,
月份整数 NOT NULL,
start_date 日期不为空,
end_date 日期不为空,
CONSTRAINT accounting_months_pkey PRIMARY KEY (id),
CONSTRAINT accounting_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 用户的每个 cmets 的索引。
表格统计
顺序扫描 48018264
顺序元组读取 4006572336
索引扫描 3251027
获取的索引元组 27236663
已插入元组 0
元组更新 0
元组已删除 0
元组 HOT 更新 0
活元组 86
死元组 0
堆块读取 3047
堆块命中 51266249
索引块读取 13
索引块命中 3251026
吐司块阅读
吐司块命中
Toast 索引块读取
Toast 索引块命中
上次真空 2014-05-05 16:46:54.087489-05
上次自动真空
最后分析 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 年 5 月 24 日》《2014 年 6 月 27 日》
附言我正在使用 Postgresql 8.3
p.s.我正在使用 Postgresql 8.4
【问题讨论】:
-
为
start_date和end_date字段添加唯一索引。 -
else 子句中的 select 语句是减慢此功能的罪魁祸首...您需要将语句更改为单个 select 而不是像这里那样的两个。
-
@Twelfth:你怎么知道?顺便说一句,我不怀疑你,但我想学习。
-
我会使用两个单独的唯一索引。
-
查询中选择行内的选择语句永远不会很好地执行,您基本上会为通过此的每条记录发生第二次查询。 2 个查询很少(几乎永远不会)胜过 1 个查询。
标签: sql postgresql sql-function