索引:
CREATE INDEX message_index ON message(queue_id, target_client_id, timestamp ASC, source_client_id);
查询:
EXPLAIN ANALYZE
SELECT content
FROM message
WHERE message.queue_id = 1
AND message.source_client_id = 1
AND (message.target_client_id = -1 OR message.target_client_id = 1);
输出:
Bitmap Heap Scan on message (cost=8.87..12.89 rows=1 width=13) (actual time=0.022..0.026 rows=50 loops=1)
Recheck Cond: (((queue_id = 1) AND (target_client_id = (-1)) AND (source_client_id = 1)) OR ((queue_id = 1) AND (target_client_id = 1) AND (source_client
_id = 1)))
-> BitmapOr (cost=8.87..8.87 rows=1 width=0) (actual time=0.017..0.017 rows=0 loops=1)
-> Bitmap Index Scan on message_index (cost=0.00..4.43 rows=1 width=0) (actual time=0.011..0.011 rows=0 loops=1)
Index Cond: ((queue_id = 1) AND (target_client_id = (-1)) AND (source_client_id = 1))
-> Bitmap Index Scan on message_index (cost=0.00..4.44 rows=1 width=0) (actual time=0.006..0.006 rows=50 loops=1)
Index Cond: ((queue_id = 1) AND (target_client_id = 1) AND (source_client_id = 1))
此查询如何使用与source_client_id
相关的索引,即复合索引中最右边的列,而不是第三列(timestamp
)参与查询所有?
根据这里的最后一个答案How important is the order of columns in indexes?,这不应该是有效的。我错过了什么?
答案 0 :(得分:0)
Postgres 可以使用除前导列之外的其他列进行索引查找 - 这不如使用最左边的列那样有效。在这种情况下,Postgres将扫描整个索引(而不是表格)。而对于最左侧列的条件,Postgres将仅从索引中检索与条件匹配的那些行。因此,效率的差异是处理的索引条目的数量。
我认为这隐藏在以下句子后面from the manual:
在索引中检查这些列右侧列的约束,因此它们可以保存对表的正确访问,但它们不会减少必须扫描的索引部分。
“这些列”指的是最左边的列。
顺便说一句:timestamp
(或date
或number
)对列来说是一个糟糕的选择的原因是它是一个保留字。但更重要的是:名称没有记录任何内容。不熟悉数据模型的人不知道你在那里存储什么。邮件发送的时间?收到邮件的时间?消息上次更新的时间?