1

我有一个表 't_table1' 包括 3 个字段:

`field1` tinyint(1) unsigned default NULL,
`field2` tinyint(1) unsigned default NULL,
`field3` tinyint(1) unsigned NOT NULL default ’0′,

和一个索引:

KEY `t_table1_index1` (`field1`,`field2`,`field3`),

当我运行这个 SQL1 时:

EXPLAIN SELECT * FROM table1 AS c WHERE c.field1 = 1 AND c.field2 = 0 AND c.field3 = 0

然后是显示:

Select type: Simple
tyle: All
possible key: t_table1_index1
key: NULL
key_len: NULL
rows: 1042
extra: Using where

我认为它说我的索引在这种情况下没用。

但是当我运行这个 SQL2 时:

EXPLAIN SELECT * FROM table1 AS c WHERE c.field1 = 1 AND c.field2 = 1 AND c.field3 = 1

表明:

Select type: Simple
tyle: ref
possible key: t_table1_index1
key: t_table1_index1
key_len: 5
ref: const, const, const
rows: 1
extra: Using where

这种情况下它使用了我的索引。所以请为我解释一下:

  1. 为什么 SQL1 不能使用索引?

  2. 使用 SQL1,我如何编辑索引或重写 SQL 以更快地执行?

谢谢 !

4

1 回答 1

0

查询优化器使用许多数据点来决定如何执行查询。其中之一是索引的选择性。使用索引可能需要比表扫描返回的每行更多的磁盘访问,因为引擎必须读取索引然后获取实际行(除非可以仅从索引满足整个查询)。随着索引的选择性降低(即更多行符合条件),使用该索引的效率会下降。在某些时候,进行全表扫描会变得更便宜。

在您的第二个示例中,优化器能够确定您提供的值将导致仅获取一行,因此索引查找是正确的方法。

In the first example, the values were not very selective, with an estimate of 1042 rows being returned out of 1776. Using the index would result in searching the index, building a list of selected row references and then fetching each row. With so many rows being selected, to use the index would have resulted in more work than just scanning the entire table lineraly and filtering the rows.

于 2013-01-23T20:33:18.157 回答