使用COUNT(*)优化查询

时间:2016-08-17 18:57:57

标签: sql performance postgresql database-performance

我得到了145821312行的表:/

date .getDatePicker().setMinDate(System.currentTimeMillis() - 1000);

我得到了查询:

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
);

EXPLAIN ANALYZE显示:

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"

有没有办法优化此查询?其他一些索引类型?它非常简单的查询,但我知道表中有很多数据; /或者我应该做一些agregates来获得这个计数器...

编辑:我改变了查询,这是错误的,没有计数(*),抱歉

2 个答案:

答案 0 :(得分:0)

在生产系统上查看查询的EXPLAIN (ANALYZE)输出会很有意思。

从数据库的角度来看,你可能做得不比使用该索引做得更好,而且我想说为了提高性能,你必须改进硬件:

  • 很多RAM - 至少是索引,但理想情况下整个表应该被缓存。
  • 快速I / O子系统。

答案 1 :(得分:0)

分区怎么样?会有帮助吗?

CREATE TABLE core.conversations_0
(
  CONSTRAINT conversations_0_user_id_check CHECK ((user_id % 1000) = 0)
) INHERITS (core.conversations);
...
CREATE TABLE core.conversations_1000
(    
  CONSTRAINT conversations_1000_user_id_check CHECK ((user_id % 1000) = 999)
) INHERITS (core.conversations);

索引:

CREATE INDEX conversations_0_user_id_idx
  ON core.conversations_0
  USING btree
  (user_id)
  WHERE status = 'unread'::core.message_status AND NOT deleted;
...
CREATE INDEX conversations_1000_user_id_idx
  ON core.conversations_1000
  USING btree
  (user_id)
  WHERE status = 'unread'::core.message_status AND NOT deleted;

但是,我还不知道为什么这个查询扫描所有索引?

SET constraint_exclusion = on;
EXPLAIN  ANALYZE SELECT COUNT(*) as cnt FROM core.conversations WHERE user_id=12728967 AND status='unread' AND deleted='false';

 "Aggregate  (cost=89.77..89.78 rows=1 width=0) (actual time=0.035..0.035 rows=1 loops=1)"
"  ->  Append  (cost=0.28..89.75 rows=11 width=0) (actual time=0.032..0.032 rows=0 loops=1)"
"        ->  Index Scan using conversations_user_id_idx on conversations  (cost=0.28..8.30 rows=1 width=0) (actual time=0.013..0.013 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_0_user_id_idx on conversations_0  (cost=0.12..8.14 rows=1 width=0) (actual time=0.003..0.003 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_1_user_id_idx on conversations_1  (cost=0.12..8.14 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_2_user_id_idx on conversations_2  (cost=0.12..8.14 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_3_user_id_idx on conversations_3  (cost=0.12..8.14 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_4_user_id_idx on conversations_4  (cost=0.12..8.14 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_5_user_id_idx on conversations_5  (cost=0.12..8.14 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_6_user_id_idx on conversations_6  (cost=0.12..8.14 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_7_user_id_idx on conversations_7  (cost=0.12..8.14 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_8_user_id_idx on conversations_8  (cost=0.12..8.14 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"        ->  Index Scan using conversations_9_user_id_idx on conversations_9  (cost=0.12..8.14 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"Planning time: 1.229 ms"
"Execution time: 0.133 ms"

编辑:

将此添加到查询' user_id%10 = 7'

SET constraint_exclusion = on;
EXPLAIN  ANALYZE SELECT COUNT(*) as cnt FROM core.conversations WHERE user_id=12728967 AND user_id%10 = 7 AND status='unread' AND deleted='false';

"Aggregate  (cost=16.46..16.47 rows=1 width=0) (actual time=0.019..0.019 rows=1 loops=1)"
"  ->  Append  (cost=0.28..16.45 rows=2 width=0) (actual time=0.015..0.015 rows=0 loops=1)"
"        ->  Index Scan using conversations_user_id_idx on conversations  (cost=0.28..8.30 rows=1 width=0) (actual time=0.013..0.013 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"              Filter: ((user_id % 10) = 7)"
"        ->  Index Scan using conversations_7_user_id_idx on conversations_7  (cost=0.12..8.15 rows=1 width=0) (actual time=0.002..0.002 rows=0 loops=1)"
"              Index Cond: (user_id = 12728967)"
"              Filter: ((user_id % 10) = 7)"
"Planning time: 0.950 ms"
"Execution time: 0.070 ms"

但它也扫描了母亲'表大索引; /