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