索引布尔字段是否有任何性能提升?

时间:2012-05-09 21:56:13

标签: mysql indexing innodb

我即将编写一个包含WHERE isok=1的查询。顾名思义,isok是一个布尔字段(实际上是TINYINT(1) UNSIGNED,根据需要设置为0或1)。

索引此字段是否有任何性能提升?引擎(在这种情况下是InnoDB)是否会更好或更差地查找索引?

7 个答案:

答案 0 :(得分:85)

这里只是为了对其他几个答案提出一个更好的观点,因为根据我的经验,那些看到这样的问题的人和我们在同一条船上,我们都听说索引布尔字段是毫无意义的,但是......

我们有一个大约有400万行的表,一次只有大约1000左右会有一个布尔开关标记,这就是我们搜索的内容。在我们的布尔字段上添加一个索引,加快了查询的数量级,从大约9秒到几分之一秒。

答案 1 :(得分:59)

不是真的。你应该把它想象成一本书。如果一本书中只有3种单词并且您将所有单词编入索引,那么您将拥有与普通页面相同数量的索引页面。

如果一个值的记录相对较少,则会有性能提升。例如,如果您有1000条记录,其中10条记录为TRUE,那么如果您使用isok = 1

进行搜索会很有用

正如迈克尔·达兰特所提到的那样,它也会使写入速度变慢。

编辑:可能重复:Indexing boolean fields

这里解释说,即使您有索引,如果您有太多记录,它也不会使用索引。 MySQL not using index when checking = 1 , but using it with = 0

答案 2 :(得分:20)

这取决于实际查询和索引/查询组合的选择性。

案例A :条件WHERE isok = 1并且没有其他任何内容:

SELECT *
FROM tableX
WHERE isok = 1
  • 如果索引足够有选择性(假设你有1M行且只有1k有isok = 1),则SQL引擎可能使用索引并且比没有索引更快它

  • 如果索引没有足够的选择性(假设你有1M行且超过100k有isok = 1),那么SQL引擎可能不使用索引并且做表扫描。

案例B :条件WHERE isok = 1以及更多内容:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

然后,它取决于您拥有的其他索引。 another_column上的索引可能比isok上只有两个可能值的索引更具选择性。 (another_column, isok)(isok, another_column)的索引会更好。

答案 3 :(得分:7)

不,通常不会。

当它们具有高选择性/基数时,通常会为要搜索的字段编制索引。 在大多数表中,布尔字段的基数非常低。 它也会使你的写入速度变慢。

答案 4 :(得分:4)

是的,索引会提高性能,检查带有和不带索引的EXPLAIN的输出。

来自文档:

  

索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后读取整个表以查找相关行。表越大,成本越高。如果表中有相关​​列的索引,MySQL可以快速确定要在数据文件中间寻找的位置,而无需查看所有数据。

我认为在这种情况下,索引不会降低的表现也是安全的,所以你只能从中获益。

答案 5 :(得分:4)

这取决于数据的分布。

想象一下,我有一本包含1000个密切打印页面的书,我书中唯一的单词是“是”'并且没有'反复重复并随机分发。如果我被要求圈出所有'是'的实例,那么本书后面的索引会有帮助吗?这取决于。

如果有一半是随机分布的是和否,那么在索引中查找就不会有帮助。该索引会使这本书变得更大,无论如何我只是从前面开始更快,并在我的每一页上找工作,寻找所有'是'并圈选它们,而不是查找索引中的每个项目,然后从索引条目中引用它引用的页面。

但是,如果有,那么,只有十个“是”'在我的千页书中,其他一切都只有数百万,所以索引可以节省我很多时间来找到这十个' yes'并盘旋它们。

数据库中的情况相同。如果它的分布是50:50,那么索引就无法提供帮助 - 数据库引擎最好只是从头到尾完成数据(全表扫描),而索引只会使数据库越大,写入和更新速度越慢。但是如果它类似于4000:1的分布(根据 oucil 在这个帖子中),那么索引搜索可以大大加快它,如果它是你想要的4000个项目中的1个

答案 6 :(得分:3)

实际上这取决于您运行的查询。但是,通常是的,以及索引任何其他类型的字段。