【发布时间】:2016-08-17 18:57:57
【问题描述】:
我的表格有 145821312 行:/
CREATE TABLE core.conversations
(
user_id integer NOT NULL,
user_to_id integer NOT NULL,
last_message_timestamp timestamp with time zone NOT NULL,
body text NOT NULL,
status core.message_status DEFAULT 'unread'::core.message_status,
my_message boolean NOT NULL,
delete_message_timestamp timestamp with time zone,
deleted boolean NOT NULL DEFAULT false,
CONSTRAINT userid_usertiid UNIQUE (, )
)
WITH (
OIDS=FALSE
);
我有疑问:
SELECT COUNT(*) FROM core.conversations WHERE user_id=xxxx AND status='unread' AND deleted='false';
解释分析显示:
"Aggregate (cost=930.17..930.18 rows=1 width=0) (actual time=0.027..0.027 rows=1 loops=1)"
" -> Index Only Scan using useridunreaddeleted_idx on conversations (cost=0.57..929.59 rows=229 width=0) (actual time=0.019..0.019 rows=0 loops=1)"
" Index Cond: ((user_id = 123123) AND (status = 'unread'::core.message_status) AND (deleted = false))"
" Filter: (NOT deleted)"
" Heap Fetches: 0"
"Planning time: 0.239 ms"
"Execution time: 0.130 ms"
索引:
CREATE INDEX useridunreaddeleted_idx
ON core.conversations
USING btree
(user_id, status, deleted);
有没有办法优化这个查询?其他一些索引类型?它的查询非常简单,但我知道表中有很多数据;/ 或者我应该做一些聚合来获得这个计数器...
编辑:我更改了查询,这是错误的,没有计数(*),对不起
【问题讨论】:
-
“执行时间:0.066 毫秒” 您的查询用时不到一秒,您想加快 o.0 吗?
-
它现在被缓存了......这个生产中的查询大约需要 5-15 秒。并且有更多的“重度”用户,有更多未读消息......
-
5-15 秒可能是最好的。也就是说,您可以尝试使用部分索引,例如
CREATE INDEX ON core.conversations (user_id) WHERE status = 'unread'::core.message_status AND NOT deleted。如果不出意外,这应该会减少您的索引大小。 -
我会交换索引中的
status和deleted列(或者甚至首先让status具有非空值和更高的选择性。当然只有状态实际上分布良好。 -
如果您关心的是生产环境中查询的性能,那么提供该执行计划是有意义的。
标签: sql performance postgresql database-performance