我有一张大桌子:
CREATE TABLE "orders" (
"id" serial NOT NULL,
"person_id" int4,
"created" int4,
CONSTRAINT "orders_pkey" PRIMARY KEY ("id")
);
所有请求中有90%与最近2-3天的订单有关person_id
,例如:
select * from orders
where person_id = 1
and created >= extract(epoch from current_timestamp)::int - 60 * 60 * 24 * 3;
如何提高性能?
我知道分区,但是现有行呢?看来我需要INHERITS
每2-3天手动创建表格。
一个 部分,多列索引
上(person_id, created)
与伪IMMUTABLE
状态将有助于(很多)。需要不时地重新创建以保持性能。
注意,如果表不是很大,则可以在很大程度上简化和使用普通的多列索引。
或者考虑在Postgres
12或更高版本(功能最终成熟的地方)中进行表分区。
一个原始 函数 提供了一个恒定的时间点,即3天或更早的时间(在您的情况下以unix纪元表示):
CREATE OR REPLACE FUNCTION f_orders_idx_start()
RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE COST 1 AS
'SELECT 1387497600';
PARALLEL SAFE
仅适用于Postgres 10或更高版本。
1387497600
由于以下原因:
SELECT extract(epoch from now())::integer - 259200;
-- 259200 being the result of 60 * 60 * 24 * 3
将 部分索引 基于此伪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; -- actual condition
该行AND created >= f_orders_idx_start()
似乎是多余的,但有助于说服Postgres使用部分索引。
一个 函数来重建功能和指标 不时。可能每天晚上都做一次正式工作:
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 format('
CREATE OR REPLACE FUNCTION f_orders_idx_start()
RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE COST 1 AS
$$SELECT %s $$'
, _start
);
-- 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
如果由于并发负载而无法删除和重新创建索引,请考虑REINDEX CONCURRENTLY
使用Postgres 12或更高版本。简直太简单了:
REINDEX INDEX orders_created_recent_idx;
即使您从未调用此函数,所有查询仍将继续工作。 随着部分索引的增加,性能会随着时间的推移而缓慢下降。
我已经成功地将这种html" target="_blank">机制与几个大型表和类似的需求结合使用了。 非常快。
对于Postgres 9.2或更高版本,并且如果您的表只有很少的小列,并且该表的写入量不大,则可能需要花一个
覆盖索引 :
CREATE INDEX orders_created_recent_idx ON orders (person_id, created **, id** )
WHERE created >= f_orders_idx_start();
在Postgres
11或更高版本中,您可能要使用INCLUDE
:
CREATE INDEX orders_created_recent_idx ON orders (person_id, created) **INCLUDE (id)**
WHERE created >= f_orders_idx_start();
我有一个需要50秒的查询 security_tasks中的记录=841321 relations中的记录=234254 我能做些什么让它快一点,比如快1秒或2秒 有什么想法吗?
问题内容: 我不太擅长SQL,因此我要求你们提供有关编写查询的帮助。 [SQL查询-表连接问题]https://codingdict.com/questions/208252) 我得到了答案,并且可以正常工作!它只是明显的缓慢。我讨厌这样做,但是我真的希望有人在那里推荐一些优化查询的方法。我什至没有自己尝试过,因为我对SQL不够了解,甚至无法开始使用谷歌搜索。 问题答案: 可能有帮助的是在要加入的
本文向大家介绍Mysql查询最近一条记录的sql语句(优化篇),包括了Mysql查询最近一条记录的sql语句(优化篇)的使用技巧和注意事项,需要的朋友参考一下 下策——查询出结果后将时间排序后取第一条 这样做虽然可以取出当前时间最近的一条记录,但是一次查询需要将表遍历一遍,对于百万以上数据查询将比较费时;limit是先取出全部结果,然后取第一条,相当于查询中占用了不必要的时间和空间;还有如果需要批
问题内容: 我的表有数百万行,我需要加入这些行才能进行选择。响应时间不是很好,如何改善响应?我尝试将索引添加到我选择的列中,是否可以使用某个工具来优化sql或如何诊断sql的瓶颈并加以改进?任何建议将不胜感激。我正在使用oracle服务器10g,并使用asp.net作为我的客户端。在具有数百万行的表上是否还有其他类型的索引有用吗? 问题答案: 您可能应该从EXPLAIN PLAN 开始。 使用EX
真心求解! Mysql 两表联查,A表900w, B表1000w, 分页查询经过索引构建已经没什么问题, 但是count(id)的时候非常慢, 怎么优化 SELECT count(distinct A.id) FROM A INNER JOIN B ON A.id = B.bus_id WHERE A.trade_type in (0,1,2,4) and B.user_id IN (68305,
为了提高配置单元查询的性能,有哪些优化参数 配置单元版本:-Hive 0.13.1-cdh5.2.1 配置单元查询:- 设置hive.exec.parallel=true; 您能建议任何其他设置,除了以上,以提高配置单元查询的性能,我正在使用的类型查询。