字符串连接正在减慢查询速度:
date(extract(YEAR FROM m.taken)||'-1-1') d1,
date(extract(YEAR FROM m.taken)||'-1-31') d2
这在代码中实现为字符串的一部分,后面是p_
变量是整数,由最终用户提供输入):
date(extract(YEAR FROM m.taken)||''-'||p_month1||'-'||p_day1||''') d1,
date(extract(YEAR FROM m.taken)||''-'||p_month2||'-'||p_day2||''') d2
查询的这一部分在3.2秒内运行日期,1.5秒没有,这让我相信有充足的改进空间。
查询的总运行时间小于10秒;我希望将整个查询降低到大约2或3秒。硬件升级已经发生。 ; - )
PostgreSQL 8.4.4。
创建日期的更好方法是什么(可能没有连接)?
这看起来很有希望:PGTYPESdate_mdyjul
非常感谢!
答案 0 :(得分:2)
可悲的是,我认为没有其他方法可以建立一个没有文本连接的日期。
是的,坦率地说,我不喜欢Postgresql在这里有的方法。似乎大多数日期操作必须通过将日期字段提取为整数,将它们作为文本转换,将它们附加到更多文本以创建日期的文本表示,然后告诉postgres将该文本解析为日期来进行...这种气味对我不好,我本能地认为通过解析字符串来建立日期应该只从文本输入中完成。但是,我认为,postgresql与处理文本表示的数据类型联系太强烈。因此,例如,如果我想从三个整数值(D,M,Y)构建一个日期,我必须(如果我没有记错)构建一个字符串并让PG解析它。我觉得这样做不干净......
除此之外,我怀疑这会降低你的表现。
答案 1 :(得分:1)
哇。我很惊讶,但使用this page中的函数 - 特别是从三个整数构建日期值的函数 - 实际上没有更多地暴露内部C日期函数,实际上要快得多。对我来说,基准测试表明,以这种方式创建日期要快得多。
第一个是“dateserial”函数的实现:
postgres=# select to_date(a,1,3)
postgres-# from generate_series(100,1000000) as v(a);
Time: 1365.851 ms
postgres=# select (a::text||'-01-03')::date from
postgres-# generate_series(100,1000000) as v(a);
Time: 3454.224 ms
修改dateserial.c
:
#include "postgres.h"
#include "utils/date.h"
#include "utils/nabstime.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
Datum dateserial(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1 (dateserial);
Datum
dateserial(PG_FUNCTION_ARGS) {
int32 p_year = PG_GETARG_INT32(0);
int32 p_month = PG_GETARG_INT32(1);
int32 p_day = PG_GETARG_INT32(2);
PG_RETURN_DATEADT( date2j( p_year, p_month, p_day ) - POSTGRES_EPOCH_JDATE );
}
修改Makefile
:
MODULES = dateserial
PGXS := $(shell pg_config --pgxs)
include $(PGXS)
修改inst.sh
(可选):
#!/bin/bash
make clean && make && strip *.so && make install && /etc/init.d/postgresql-8.4 restart
运行bash inst.sh
。
创建SQL函数dateserial
:
CREATE OR REPLACE FUNCTION dateserial(integer, integer, integer)
RETURNS date AS
'$libdir/dateserial', 'dateserial'
LANGUAGE 'c' IMMUTABLE STRICT
COST 1;
ALTER FUNCTION dateserial(integer, integer, integer) OWNER TO postgres;
测试功能:
SELECT dateserial( 2007::int, 5, 5 )
答案 2 :(得分:0)
另一种方法是在连接上创建function index。这适用于没有更好数据类型的更一般情况。