我主要是一个Actionscript开发人员,绝不是SQL专家,但我不得不开发简单的服务器端.所以,我想我会在标题中向更有经验的人询问这个问题.
我的理解是,通过在一个包含很少不同值的列中设置索引,您不会获得太多收益.我有一个包含布尔值的列(实际上它是一个小的int,但我将它用作标志),并且此列用于我所拥有的大多数查询的WHERE子句中.在理论上的"平均"情况下,一半的记录值将为1而另一半为0.因此,在这种情况下,数据库引擎可以避免全表扫描,但无论如何都必须读取大量行(总行/ 2).
那么,我应该将此列作为索引吗?
为了记录,我正在使用Mysql 5,但是我更感兴趣的是一般的理由,为什么它有/无意义索引一个我知道将具有低基数的列.
提前致谢.
如果出现以下情况,索引甚至可以帮助低基数字段:
当其中一个可能的值与其他值相比非常罕见并且您搜索它时.
例如,色盲女性很少,所以这个查询:
SELECT * FROM color_blind_people WHERE gender = 'F'
最有可能从指数中受益gender
.
当值倾向于按表顺序分组时:
SELECT * FROM records_from_2008 WHERE year = 2010 LIMIT 1
尽管这里只有3
不同的年份,但是最早的年份记录很可能首先被添加,因此2010
如果不是索引,则必须在返回第一条记录之前扫描很多记录.
需要时ORDER BY / LIMIT
:
SELECT * FROM people ORDER BY gender, id LIMIT 1
如果没有索引,则filesort
需要a.虽然它有点优化LIMIT
,但它仍然需要全表扫描.
当索引涵盖查询中使用的所有字段时:
CREATE INDEX (low_cardinality_record, value) SELECT SUM(value) FROM mytable WHERE low_cardinality_record = 3
需要时DISTINCT
:
SELECT DISTINCT color FROM tshirts
MySQL
将使用INDEX FOR GROUP-BY
,如果您的颜色很少,即使拥有数百万条记录,此查询也将立即生效.
这是低基数字段上的索引比高基数字段上的索引更有效的情况的示例.
请注意,如果DML
性能不是很大,那么创建索引是安全的.
如果优化器认为索引效率低下,则不会使用索引.
可能值得在复合索引中包含布尔字段.例如,如果你有一个大的消息表,通常需要按日期排序,但你也有一个布尔删除字段,所以你经常查询它:
SELECT ... FROM Messages WHERE Deleted = 0 AND Date BETWEEN @start AND @end
您肯定会从Deleted和Date字段上的复合索引中受益.