mysql> explain select * from company2 where name like '%3'\G; **************************** 1. row ************************************* id: 1 select_type: SIMPLE table: company2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set(0.00 sec)
mysql> explain select * from company2 where name like '3%'\G; **************************** 1. row ************************************* id: 1 select_type: SIMPLE table: company2 type: range possible_keys: ind_company2_name key: ind_company2_name key_len: 11 ref: NULL rows: 103 Extra: Using where 1 row in set(0.00 sec)
(4)如果列名是索引,使用 column_name is null 将使用索引。如下例中查询 name 为 null 的记录就用到了索引:
1 2 3 4 5 6 7 8 9 10 11 12 13
mysql> explain select * from company2 where name is null\G; **************************** 1. row ************************************* id: 1 select_type: SIMPLE table: company2 type: ref possible_keys: ind_company2_name key: ind_company2_name key_len: 11 ref: const rows: 1 Extra: Using where 1 row in set(0.00 sec)
存在索引但不使用索引
在下列情况下,虽然存在索引,但是 MySQL 并不会使用相应的索引。
(1)如果 MySQL 估计使用索引比全表扫描更慢,则不使用索引。例如如果列 key_part1 均匀分布在 1 和 100 之间,下列查询中使用索引就不是很好:
1
SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90;
(2)如果使用 MEMORY/HEAP 表并且 where 条件中不使用“=”进行索引列,那么不会用到索引。heap 表只有在“=”的条件下才会使用索引。
(3)用 or 分割开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及到的索引都不会被用到,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mysql> show index from sales\G; **************************** 1. row ************************************* Table: sales Non_unique: 1 Key_name: ind_sales_year Seq_in_index: 1 Column_name: year Collation: A Cardinality: NULL Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: 1 row in set(0.00 sec)
从上面可以发现只有 year 列上面有索引,来看如下的执行计划:
1 2 3 4 5 6 7 8 9 10 11 12 13
mysql> explain select * from sales where year = 2001 or country = 'China'\G; **************************** 1. row ************************************* id: 1 select_type: SIMPLE table: sales type: ALL possible_keys: ind_sales_year key: NULL key_len: NULL ref: NULL rows: 12 Extra: Using where 1 row in set(0.00 sec)
可见虽然在 year 这个列上存在索引 ind_sales_year,但是这个 SQL 语句并没有用到这个索引,原因就是 or 中有一个条件中的列没有索引。
(4)如果不是索引列的第一部分,如下例子:
1 2 3 4 5 6 7 8 9 10 11 12 13
mysql> explain select * from sales2 where moneys = 1\G; **************************** 1. row ************************************* id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set(0.00 sec)
可见虽然在 money 上面建有复合索引,但是由于 money 不是索引的第一列,那么在查询中这个索引也不会被 MySQL 采用。
(5)如果 like 是以 % 开始,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13
mysql> explain select * from company2 where name like '%3'\G; **************************** 1. row ************************************* id: 1 select_type: SIMPLE table: company2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set(0.00 sec)
可见虽然在 name 上建有索引,但是由于 where 条件中 like 的值的“%”在第一位了,那么 MySQL 也不会采用这个索引。
(6)如果列类型是字符串,那么一定记得在 where 条件中把字符常量值用引号引起来,否则的话即便这个列上有索引,MySQL 也不会用到的,因为,MySQL 默认把输入的常量值进行转换以后才进行检索。如下面的例子中 company2 表中的 name 字段是字符型的,但是 SQL 语句中的条件值 294 是一个数值型值,因此即便在 name 上有索引,MySQL 也不能正确地用上索引,而是继续进行全表扫描。
MySQL 客户端连接成功后,通过 show[session|global] status 命令可以提供服务器状态信息,也可以在操作系统上使用 mysqladmin extended-status 命令获得这些消息。show[session|global] status 可以根据需要加上参数“session”或者“global”来显示 session 级(当前连接)的统计结果和 global 级(自数据库上次启动至今)的统计结果。如果不写,默认使用参数是“session”。
插件式存储引擎是 MySQL 数据库最重要的特性之一,用户可以根据应用的需要选择如何存储和索引数据、是否使用事务等。MySQL 默认支持多种存储引擎,以适用于不同领域的数据库应用需要,用户可以通过选择使用不同的存储引擎提高应用的效率,提供灵活的存储,用户甚至可以按照自己的需要定制和使用自己的存储引擎,以实现最大程度的可定制性。
MySQL 5.0 支持的存储引擎包括 MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED 等,其中 InnoDB 和 BDB 提供事务安全表,其它存储引擎都是非事务安全表。
特性
下面列出几种常见的存储引擎,并对比之间的区别。
特点
MyISAM
InnoDB
MEMORY
MERGE
NDB
存储限制
有
64TB
有
没有
有
事务安全
支持
锁机制
表锁
行锁
表锁
表锁
行锁
B 树索引
支持
支持
支持
支持
支持
哈希索引
支持
支持
全文索引
支持
集群索引
支持
数据缓存
支持
支持
支持
索引缓存
支持
支持
支持
支持
支持
数据可压缩
支持
空间使用
低
高
N/A
低
低
内存使用
低
高
中等
低
高
批量插入的速度
高
低
高
高
高
支持外键
支持
本文重点介绍最常遇到的两种存储引擎:MyISAM 和 InnoDB。
MyISAM
MyISAM 是 MySQL 的默认存储引擎。MyISAM 不支持事务、也不支持外键,其优势是访问的速度快,对事务完整性没有要求或者以 SELECT、INSERT 为主的应用基本上都可以使用这个引擎来创建表。