索引:
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 = 5 AND message.source_client_id = 5 AND (message.target_client_id = -1 OR message.target_client_id = 5) ORDER BY timestamp ASC LIMIT 1;
输出:
Sort (cost=8.39..8.39 rows=1 width=13) (actual time=0.014..0.014 rows=0 loops=1)
Sort Key: "timestamp"
Sort Method: quicksort Memory: 25kB
-> Index Scan using message_index on message (cost=0.27..8.38 rows=1 width=13) (actual time=0.011..0.011 rows=0 loops=1)
Index Cond: ((queue_id = 5) AND (source_client_id = 5))
Filter: ((target_client_id = (-1)) OR (target_client_id = 5))
Total runtime: 0.034 ms
为什么postgres在开始时执行快速排序,为什么它不使用索引中的timestamp属性?什么(...... rows = 1)是什么意思?
答案 0 :(得分:2)
排序在结束完成,而不是在开头。
您必须从最内层节点(Index Scan using message_index on message
开始,然后“上升树”开始阅读执行计划。
所以执行顺序是
timestamp
列对检索到的行进行排序(btw是列的可怕名称)第一对括号中的rows=1
表示Postgres 期望(估计)此步骤仅返回一行。第二部分中的row=0
表示实际上没有基于where
条件返回的行。
手册中说明了输出的各个部分:
http://www.postgresql.org/docs/current/static/using-explain.html
您还可以阅读本网站提供的信息:
http://use-the-index-luke.com/
答案 1 :(得分:0)
它不能使用索引来提供排序,因为target_client_id
在索引定义中位于timestamp
之前,并且在where子句中未指定target_client_id
与单个值相等。< / p>
理论上,这样的索引可用于通过执行两个索引扫描来提供排序,每个索引扫描对应于target_client_id
的每个指定值,以便为每个索引扫描获取行。然后它将合并两个有序流。但PostgreSQL并没有编写这种类型的优化。 (在这种情况下,它可能实际上不是优化。)
是的,如果它返回超过1行的话就会排序。