我即将编写一个包含WHERE isok=1
的查询。顾名思义,isok
是一个布尔字段(实际上是TINYINT(1) UNSIGNED
,根据需要设置为0或1)。
索引此字段是否有任何性能提升?引擎(在这种情况下是InnoDB)是否会更好或更差地查找索引?
答案 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)
实际上这取决于您运行的查询。但是,通常是的,以及索引任何其他类型的字段。