我建议在(person_id, created)
一个partial multicolumn index用伪IMMUTABLE
条件,这需要从不时被重建,以保持性能最高。
注意,如果你的表格不是很大,你可以在很大程度上简化和使用一个普通的多列索引。
甲原始函数提供在时间恒定的点,3个或更多天回(由UNIX划时代你的情况表示):
CREATE OR REPLACE FUNCTION f_orders_idx_start()
RETURNS integer AS
'SELECT 1387497600'
LANGUAGE sql IMMUTABLE COST 1;
1387497600
是的SELECT extract(epoch from now())::integer - 259200;
结果。
在此基础上伪IMMUTABLE
条件的部分指数:
CREATE INDEX orders_created_recent_idx ON orders (person_id, created)
WHERE created >= f_orders_idx_start();
基地的查询在同一个 “恒”:
SELECT *
FROM orders
WHERE person_id = 1
AND created >= f_orders_idx_start() -- match partial idx. condition
AND created >= extract(epoch from now())::integer - 259200;
-- 259200 being the result of 60 * 60 * 24 * 3
线AND created >= f_orders_idx_start()
似乎是多余的,但有助于说服Postgres使用部分索引。
A 函数重新创建函数和索引不时。可能有一个cron作业每天晚上:
CREATE OR REPLACE FUNCTION f_orders_reindex_partial()
RETURNS void AS
$func$
DECLARE
-- 3 days back, starting at 00:00
_start int := extract(epoch from now()::date -3)::int;
BEGIN
IF _start = f_orders_idx_start() THEN
-- do nothing, nothing changes.
ELSE
DROP INDEX IF EXISTS orders_created_recent_idx;
-- Recreate IMMUTABLE function
EXECUTE '
CREATE OR REPLACE FUNCTION f_orders_idx_start()
RETURNS integer AS
$$SELECT ' || _start || '$$
LANGUAGE sql IMMUTABLE COST 1';
-- Recreate partial index
CREATE INDEX orders_created_recent_idx ON orders (person_id, created)
WHERE created >= f_orders_idx_start();
END IF;
END
$func$ LANGUAGE plpgsql;
电话:
SELECT f_orders_reindex_partial(); -- that's all
所有查询继续工作,即使你从来没有调用这个函数。随着偏股指数的增长,业绩慢慢恶化。
我使用这个政权成功地与几个大表和类似的要求。 非常快。
Postgres的9.2或更高版本,如果你的表只有几个,小列,如果表没有被大量写的,它可能会有好一个covering index:
CREATE INDEX orders_created_recent_idx ON orders (person_id, created, id)
WHERE created >= f_orders_idx_start();
你知道[索引](http://www.postgresql.org/docs/9.3/static/indexes-intro.html)? –
是的,当然,我已经有索引(person_id,创建) – user2024300
刚刚创建'创建'索引有什么错?我看不出分区如何对此有所帮助。这将成为一个低效率的指数。所以只需要首先创建索引。 – usr