Ничего себе. Я удивлен, но использование функций из этой страницы - в частности, той, которая строит значение даты из трех целых чисел - которые на самом деле больше ничего не делают для раскрытия внутренних функций даты Си, действительно намного быстрее. Бенчмаркинг для меня показывает, что создание дат таким образом было намного быстрее.
Первый - реализация функции 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 )