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

Nie*_*sol 87 mysql indexing innodb

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

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

ouc*_*cil 98

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

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

  • @Eelco你是对的,但在这种情况下,结果实际上与基本理论很吻合.如果您有大约50%的可能遇到与您的搜索匹配的项目,那么它应该可以忽略不计的基本想法才有意义.然后,要查找100个匹配项,数据库需要迭代200个项目.但如果项目只占1%的时间,则需要迭代10,000个项目. (8认同)
  • 这应该是公认的答案 (4认同)
  • 我喜欢人们实际在现场进行尝试并给出性能提升反馈,而不仅仅是哲学思考。 (3认同)

Mic*_*per 64

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

如果一个值的记录相对较少,则会有性能提升.例如,如果您有1000条记录,其中10条为TRUE,那么在您搜索时它会很有用isok = 1

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

编辑:可能的重复:索引布尔字段

这里解释说即使你有一个索引,如果你有太多的记录,它也不会使用索引. MySQL在检查= 1时不使用索引,但在= 0时使用它

  • 看起来像是"是:2 - 否:1".有人在这里错了,但谁呢? (4认同)
  • 这不完全正确,没有索引mySql需要扫描整个表来查找相关行. (4认同)
  • 否则会扫描整个索引.(在大多数情况下也一样长) (4认同)
  • 假设TRUE和FALSE之间的分配相等.如下面的@oucil所述,如果你正在寻找一个相当罕见的布尔值,它可能还需要一段时间.不是说你应该总是索引,但我会假设你的数据的性质,你的查询在大多数数据库引擎下也很重要. (4认同)
  • 它可以发挥作用。只需添加索引即可将查询的执行时间减少一半,并且写入很少且足够便宜,因此我们并不真正关心惩罚。与所有事情一样,不要假设,而是测量(也因为数据库实际上并不总是像您逻辑上期望的那样运行) (3认同)
  • @EdMassey - 不,RAM 与磁盘中的位置并没有那么简单。所有块(数据或索引)都根据需要在 buffer_pool 中“缓存”。所以任何一个块都可能在内存中,也可能不在内存中。 (2认同)

ype*_*eᵀᴹ 23

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

案例A:条件WHERE isok = 1,没有别的:

SELECT *
FROM tableX
WHERE isok = 1
Run Code Online (Sandbox Code Playgroud)
  • 如果索引足够有选择性(假设你有1M行而且只有1k isok = 1),那么SQL引擎可能会使用索引并且比没有索引更快.

  • 如果索引没有足够的选择性(假设您有1M行且超过100k isok = 1),则SQL引擎可能不会使用索引并执行表扫描.

案例B:条件WHERE isok = 1和更多东西:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17
Run Code Online (Sandbox Code Playgroud)

然后,它取决于你有什么其他索引.索引another_column可能比isok只有两个可能值的索引更具选择性.指数(another_column, isok)(isok, another_column)将会更好.


Jin*_*lye 6

这取决于数据的分布。

想象一下,我有一本书,其中有1000个紧密键入的页面,而书中唯一的单词是“ yes”和“ no”,一遍又一遍地重复并随机分布。如果要求我圈出“是”的所有实例,书后的索引是否有帮助?这取决于。

如果存在是和否的一半随机分布,那么在索引中查找将无济于事。索引会使书变大得多,无论如何,我会更快地从头开始,并逐步浏览每一页以查找“是”的所有实例并圈出它们,而不是查找其中的每个项目。索引,然后从索引条目中获取对引用的页面的引用。

但是,如果说,在我的一千页的书中只有十个“是”的实例,而其他所有内容都只有数百万个“不是”,那么索引将为我节省寻找这十个“是”的实例并将其圈出的时间。

在数据库中也是一样。如果是50:50的分布,那么索引将无济于事-数据库引擎最好只是从头到尾地浏览数据(全表扫描),而索引只会使数据库更大,并且编写和更新速度较慢。但是,如果它类似于4000:1分布(按照该线程中的oucil),则索引查找可以极大地加快它的速度,如果它是您要查找的4000个项目中的1个。


Mic*_*ant 5

不,通常不是.

您通常在具有高选择性/基数的情况下索引字段以进行搜索.在大多数表中,布尔字段的基数非常低.它也会使你的写入速度略慢.