我正在阅读高性能MySQL这本书,并且正在使用新的数据库来测试一些事情。
我不确定我做错了什么..
我有一张名为table_users
结构:
ID(Integer)
FullName(Char)
UserName(Char)
Password(Char)
SecurityID(TinyINT)
LocationID(TinyINT)
Active(TinyINT)
我的索引如下:
PRIMARY : ID
FullName : UNIQUE : FullName
FK_table_users_LocationID (foreign key reference) : INDEX : LocationID
FK_table_users_SecurityID (foreign key reference) : INDEX : SecurityID
Active : INDEX : Active
所有人都是BTREE
在阅读本书时,我试图使用以下mysql语句来查看SELECT语句所涉及的额外内容
EXPLAIN
SELECT * FROM table_users WHERE
FullName = 'Jeff';
无论WHERE语句指向此调用的是什么,额外的结果都是无效或使用where。如果我选择ID ... WHERE FullName ='Jeff'它返回使用where,Using Index。但不是每当我执行SELECT FullName .... WHERE FullName ='Jeff'..
我对索引并不熟悉,并且试图绕过他们,对此有点混淆。如果我引用索引列,它们不应该返回使用索引吗?
感谢。
答案 0 :(得分:2)
使用索引并不意味着它的意思。看看覆盖索引。如果它说“使用索引”,则意味着mysql可以在不读取实际行的情况下返回查询数据。 SELECT * - 只有在表中的列甚至在索引中时才能使用覆盖索引。通常情况并非如此。
我似乎记得高性能Mysql中的章节讨论了覆盖索引以及如何阅读EXPLAIN结果。
答案 1 :(得分:1)
您使用的是哪个版本的MySQL?这是我在Percona Server 5.5.16上运行的测试:
mysql> create table table_users (
id int auto_increment primary key,
fullname char(20),
username char(20),
unique key (fullname)
);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into table_users values (default, 'billk', 'billk');
Query OK, 1 row affected (0.00 sec)
mysql> explain select * from table_users where fullname='billk'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: table_users
type: const
possible_keys: fullname
key: fullname
key_len: 21
ref: const
rows: 1
Extra:
1 row in set (0.00 sec)
这表明它正在使用全名索引,以常量值查找,但它不是仅索引查询。
mysql> explain select fullname from table_users where fullname='billk'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: table_users
type: const
possible_keys: fullname
key: fullname
key_len: 21
ref: const
rows: 1
Extra: Using index
1 row in set (0.00 sec)
这是预期的,它可以从fullname索引中获取fullname列,因此这是一个仅索引查询。
mysql> explain select id from table_users where fullname='billk'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: table_users
type: const
possible_keys: fullname
key: fullname
key_len: 21
ref: const
rows: 1
Extra: Using index
1 row in set (0.00 sec)
在fullname上搜索但是获取主键也是一个仅索引查询,因为InnoDB二级索引的叶节点(例如唯一键)隐式包含主键值。因此,此查询能够遍历BTREE以获取全名,并且作为奖励,它也会获得ID。
mysql> explain select fullname, username from table_users where fullname='billk'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: table_users
type: const
possible_keys: fullname
key: fullname
key_len: 21
ref: const
rows: 1
Extra:
1 row in set (0.00 sec)
只要select-list包含任何不属于索引的列,它就不再是仅索引查询。首先,它在BTREE中搜索全名,以查找主键值。然后它使用该id值来遍历聚簇索引的BTREE,这就是InnoDB存储整个表的方式。在那里,它找到给定行的其他列,包括用户名。