回答
由于您访问该网站use-the-index-luke.com
,请考虑以下章节:
使用索引,卢克›哪里子句›搜索范围› 更大,更少和之间
它有一个示例可以完美地满足您的情况(两列索引,一个经过相等性测试,另一个用于range),解释了(使用更多这些漂亮的索引图形)为什么@ypercube的建议是准确的并进行总结:
Rule of thumb: index for equality first — then for ranges.
也只适合一列吗?
对于仅一列的查询该怎么办似乎很清楚。在以下相关问题下,有关此方面的更多详细信息和基准:
选择性较低的列优先?
除此之外,如果两个列都只有相等条件怎么办?
没关系。将列放在最有可能接收其自身条件的列上,这实际上很重要。
考虑这个演示,或自己复制它。我创建了一个简单的表,其中包含两列,每行包含10万行。一个具有很少的值,另一个具有许多不同的值:
CREATE TEMP TABLE t AS
SELECT (random() * 10000)::int AS lots
, (random() * 4)::int AS few
FROM generate_series (1, 100000);
DELETE FROM t WHERE random() > 0.9; -- create some dead tuples, more "real-life"
ANALYZE t;
SELECT count(distinct lots) -- 9999
, count(distinct few) -- 5
FROM t;
查询:
SELECT *
FROM t
WHERE lots = 2345
AND few = 2;
EXPLAIN ANALYZE
输出(十个最佳,以排除缓存影响):
在t上进行序列扫描(成本= 0.00..5840.84行= 2宽度= 8)
(实际时间= 5.446..15.535行= 2个循环= 1)
过滤器:((手数= 2345)AND(很少= 2))
缓冲区:本地点击数= 443
总运行时间:15.557毫秒
添加索引,重新测试:
CREATE INDEX t_lf_idx ON t(lots, few);
在t上使用t_lf_idx进行索引扫描(成本= 0.00..3.76行= 2宽度= 8)
(实际时间= 0.008..0.011行= 2循环= 1)
指数条件:((手数= 2345)AND(很少= 2))
缓冲区:本地命中= 4
总运行时间:0.027毫秒
添加其他索引,重新测试:
DROP INDEX t_lf_idx;
CREATE INDEX t_fl_idx ON t(few, lots);
在t上使用t_fl_idx进行索引扫描(成本= 0.00..3.74行= 2宽度= 8)
(实际时间= 0.007..0.011行= 2循环= 1)
索引条件:([few = 2)AND(lots = 2345))
缓冲区:本地命中= 4
总运行时间:0.027毫秒