MySQL为什么不在用作布尔值的int字段上使用索引?

时间:2008-12-24 15:15:10

标签: mysql indexing

select * from myTable where myInt
即使myInt字段上有索引,

在解释查询时也不会显示任何possible_keys。

修改
 有问题的指数并不是唯一的。

4 个答案:

答案 0 :(得分:5)

要让MySQL使用索引,您必须明确地将int字段与值进行比较(例如,true,1)。

select * from myTable where myInt = true

答案 1 :(得分:2)

我不是数据库专家,但是如果该字段只有两个可能的值,它是否会破坏在该字段上建立索引的目的?

如果索引列中的所有字段都是唯一的,则数据库引擎可以执行索引扫描以查找相关行。如果只有两个可能的值 - 那么我没有看到将该字段编入索引的目的。数据库引擎必须执行与索引不存在时相同的操作。

也许MySQL没有将它显示为可能的密钥,因为引擎已经放弃了在执行计划中使用索引的想法?

答案 2 :(得分:1)

有很多因素需要考虑。

不应该进入的一个因素是问题中使用的符号。当列是布尔值时,优化器应将这些条件视为相同:

SELECT * FROM MyTable WHERE MyInt;

SELECT * FROM MyTable WHERE MyInt != 0;

SELECT * FROM MyTable WHERE MyInt IS TRUE;

SELECT * FROM MyTable WHERE MyInt = TRUE;

可能还有其他等效配方。第一个不是标准的SQL(即使MyInt的类型是BOOLEAN;其他的都是标准的。但优化器应该简单地将速记转换为适当的长形式,然后表现就像长形式由user。(如果优化器没有这样做,那么优化器可能存在问题;在决定如何处理查询之前,应该将查询简化为规范形式。但是,即使是最好的优化器也经常会出现盲点学习如何避免这些是艺术形式,本质上是DBMS特定的。)

优化器在认为索引会提高查询性能时会使用索引。当索引不会提升性能时,它会被忽略(如果优化器是好的)。有时,这取决于索引的统计数据是否是最新的。

在数据仓库系统中,系统可以设计和配置为非常快速地对表进行顺序扫描;在这样的系统中,如果索引的选择性使得使用它将拉动的行数少于25%,那么执行全表扫描实际上比使用索引更快。

想一想。通过索引读取时,DBMS必须至少执行两次读取操作;它从索引页面读取有关该行的信息,然后它必须从数据页面读取该行。

某些DBMS提供仅索引表。所有数据都在索引中。其他DBMS提供了一种机制,您可以说“索引在列A,B,C上是唯一的;但是,也包括数据中的列D和E”。然后,如果查询需要来自A,B,C,D或E(或任何组合)的数据,并且对其他列没有过滤,则DBMS只需要扫描索引,而不是表格页。

通常,您会在页面中获得许多索引行。但是,对于某些表,读取索引可能需要读取比读取行更多的数据。考虑包含两个(4字节)整数ID值的原型多对多映射表。这需要数据页中每行8个字节,但索引可能需要4-8个字节的开销(因为索引键条目存储了两个ID值以及在磁盘上定位相应行所需的信息)。因此,索引扫描可能涉及两倍于数据扫描的磁盘I / O,即使索引扫描仅完成“索引”。

这几乎没有触及使用或不使用索引的可能原因。

答案 3 :(得分:0)

您的问题SQL看起来对我不正确。您在寻找列的非空值吗?这应该使用索引:

select * from myTable where myInt is not null