【发布时间】:2008-12-24 15:15:10
【问题描述】:
select * from myTable where myInt
在解释查询时不会显示任何可能的键,即使 myInt 字段上有索引。
编辑:
有问题的索引不是唯一的。
【问题讨论】:
select * from myTable where myInt
在解释查询时不会显示任何可能的键,即使 myInt 字段上有索引。
编辑:
有问题的索引不是唯一的。
【问题讨论】:
要让 MySQL 使用索引,您必须明确地将 int 字段与一个值进行比较(例如 true、1)。
select * from myTable where myInt = true
【讨论】:
我不是数据库专家,但如果字段只有两个可能的值,是否会破坏在字段上建立索引的目的?
如果索引列中的所有字段都是唯一的,那么数据库引擎可以进行索引扫描以查找相关行。如果只有两个可能的值 - 那么我看不到将该字段编入索引的目的。数据库引擎必须执行与索引不存在时相同的操作。
也许 MySQL 没有将它显示为可能的键,因为引擎已经放弃了在执行计划中使用索引的想法?
【讨论】:
有很多因素需要考虑。
一个不应该参与其中的因素是问题中使用的符号。当列是布尔值时,优化器应将这些条件视为相同:
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;其他都是标准的。但是优化器应该简单地将速记转换为适当的长格式,然后表现得与长格式是由(如果优化器不这样做,那么可以说优化器存在问题;在决定如何处理查询之前,应该将查询简化为规范形式。但是,即使是最好的优化器也经常存在盲点. 学习如何避免这些是一种艺术形式,并且本质上是 DBMS 特有的。)
当优化器认为索引会提高查询性能时,它会使用索引。当索引不会提高性能时,它会被忽略(如果优化器有任何好处)。有时,这取决于索引的统计信息是否是最新的。
在数据仓库系统中,系统可以设计和配置为非常快速地对表进行顺序扫描;在这样的系统中,如果索引的选择性使得使用它会提取超过 25% 的行,那么执行全表扫描实际上比使用索引更快。
考虑一下。通过索引读取时,DBMS 必须至少进行两次读取;它从索引页读取行的信息,然后它必须从数据页读取行。
一些 DBMS 提供仅索引表。所有数据都在索引中。其他 DBMS 提供了一种机制,您可以说“索引在 A、B、C 列上是唯一的;但是,在数据中也包括 D 和 E 列”。然后,如果查询需要来自 A、B、C、D 或 E(或任何组合)的数据,并且没有对其他列进行过滤,则 DBMS 只需扫描索引,而不是表页。
通常,您会在一个页面中获得许多索引行。但是,对于某些表,读取索引可能需要读取比读取行更多的数据。考虑包含两个(4 字节)整数 ID 值的原型多对多映射表。这需要数据页中每行 8 个字节,但索引可能需要 4-8 个字节的开销(因为索引键条目存储了两个 ID 值以及在磁盘上定位相应行所需的信息)。因此,那里的索引扫描可能涉及两倍于数据扫描的磁盘 I/O,即使索引扫描是“仅索引”完成的。
这只是触及使用或不使用索引的可能原因的表面。
【讨论】:
在我看来,您的问题的 SQL 格式不正确。您是否正在寻找列的非空值?这应该使用索引:
select * from myTable where myInt is not null
【讨论】: