WEB开发网
开发学院数据库MySQL 浅谈MySQL数据库优化 阅读

浅谈MySQL数据库优化

 2007-11-11 13:22:01 来源:WEB开发网   
核心提示: 3 SELECT优化 3.1 MySQL(和PHP搭配之最佳组合)数据库的SQL执行计划解释器 EXPLAIN tbl_name 或者如下: EXPLAIN [EXTENDED] SELECT select_options EXPLAIN tbl_name是DESCRIBE tbl_name或SHOW COLUMNS

  3 SELECT优化

3.1 MySQL(和PHP搭配之最佳组合)数据库的SQL执行计划解释器

EXPLAIN tbl_name

或者如下:

EXPLAIN [EXTENDED] SELECT select_options

EXPLAIN tbl_name是DESCRIBE tbl_name或SHOW COLUMNS FROM tbl_name的一个同义词。
MySQL(和PHP搭配之最佳组合)> explain a;+-------+---------+------+-----+---------+-------+| Field | Type    | Null | Key | Default | Extra |+-------+---------+------+-----+---------+-------+| id    | int(11) | YES  | UNI | NULL    |       |+-------+---------+------+-----+---------+-------+1 row in set (0.02 sec)MySQL(和PHP搭配之最佳组合)> explain t;+-------+-------------+------+-----+---------+-------+| Field | Type        | Null | Key | Default | Extra |+-------+-------------+------+-----+---------+-------+| id    | int(11)     | NO   | PRI | 0       |       || MC    | varchar(60) | YES  |     | NULL    |       |+-------+-------------+------+-----+---------+-------+2 rows in set (0.00 sec)MySQL(和PHP搭配之最佳组合)> select * from t;+-------+------+| id    | MC   |+-------+------+|     1 | MC   ||     2 | NULL ||     3 | NULL ||     4 | NULL ||     5 | NULL ||     6 | NULL ||     7 | NULL ||     8 | NULL ||     9 | NULL || 10000 | MC   |+-------+------+10 rows in set (0.00 sec)MySQL(和PHP搭配之最佳组合)> select * from a;+------+| id   |+------+| NULL ||    1 ||    2 |+------+3 rows in set (0.00 sec)MySQL(和PHP搭配之最佳组合)> explain select * from A where id in (select id from T)\G*************************** 1. row ***************************           id: 1  select_type: Prima(最完善的虚拟主机管理系统)RY        table: A         type: indexpossible_keys: NULL          key: idx_a      key_len: 5          ref: NULL         rows: 3        Extra: Using where; Using index*************************** 2. row ***************************           id: 2  select_type: DEPENDENT SUBQUERY        table: T         type: unique_subquerypossible_keys: Prima(最完善的虚拟主机管理系统)RY          key: Prima(最完善的虚拟主机管理系统)RY      key_len: 4          ref: func         rows: 1        Extra: Using index2 rows in set (0.02 sec)
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

index_subquery
该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:
MySQL(和PHP搭配之最佳组合)> explain select * from test where id in (select id from a)\G*************************** 1. row ***************************           id: 1  select_type: Prima(最完善的虚拟主机管理系统)RY        table: test         type: ALLpossible_keys: NULL          key: NULL      key_len: NULL          ref: NULL         rows: 1534755        Extra: Using where*************************** 2. row ***************************           id: 2  select_type: DEPENDENT SUBQUERY        table: a         type: index_subquerypossible_keys: idx_a          key: idx_a      key_len: 5          ref: func         rows: 1        Extra: Using index2 rows in set (0.00 sec)

range
索引范围扫描,只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range:
    MySQL(和PHP搭配之最佳组合)> explain select * from t where id=1 or id=10000 or id=3\G;*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t         type: rangepossible_keys: Prima(最完善的虚拟主机管理系统)RY          key: Prima(最完善的虚拟主机管理系统)RY      key_len: 4          ref: NULL         rows: 3        Extra: Using where1 row in set (0.00 sec)MySQL(和PHP搭配之最佳组合)> explain select * from t where id<=3\G;*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t         type: rangepossible_keys: Prima(最完善的虚拟主机管理系统)RY          key: Prima(最完善的虚拟主机管理系统)RY      key_len: 4          ref: NULL         rows: 4        Extra: Using where1 row in set (0.00 sec)ERROR:No query specified

index
索引全扫描,该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。当查询只使用作为单索引一部分的列时,MySQL(和PHP搭配之最佳组合)可以使用该联接类型。
MySQL(和PHP搭配之最佳组合)> explain select * from t\G;*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t         type: indexpossible_keys: NULL          key: idx_t_mc      key_len: 63          ref: NULL         rows: 10        Extra: Using index1 row in set (0.00 sec)ERROR:No query specified

ALL
全表扫描,对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记cnst的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。

MySQL(和PHP搭配之最佳组合)> explain select * from test\G;*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: test         type: ALLpossible_keys: NULL          key: NULL      key_len: NULL          ref: NULL         rows: 1534755        Extra:1 row in set (0.06 sec)ERROR:No query specified
pssible_keys
pssible_keys列指出MySQL(和PHP搭配之最佳组合)能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在pssible_keys中的某些键实际上不能按生成的表次序使用。如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询。

为了看清一张表有什么索引,使用SHOW INDEX FROM tbl_name。
MySQL(和PHP搭配之最佳组合)> show index from t;+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+| t     |          0 | Prima(最完善的虚拟主机管理系统)RY  |            1 | id          | A         |     2 |     NULL | NULL   |      | BTREE      |         || t     |          1 | idx_t_mc |            1 | MC          | A         |     2 |     NULL | NULL   | YES  | BTREE      |         |+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+2 rows in set (0.08 sec)
key
key列显示MySQL(和PHP搭配之最佳组合)实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL(和PHP搭配之最佳组合)使用或忽视pssible_keys列中的索引,在查询中使用FRCE INDEX、USE INDEX或者IGNRE INDEX。对于MyISAM和BDB表,运行ANALYZE TABLE可以帮助优化器选择更好的索引。对于MyISAM表,可以使用myisamchk --analyze。
MySQL(和PHP搭配之最佳组合)> explain select * from t where id=1 or mc='1'\G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t         type: indexpossible_keys: Prima(最完善的虚拟主机管理系统)RY,idx_t_mc          key: idx_t_mc      key_len: 63          ref: NULL         rows: 10        Extra: Using where; Using index1 row in set (0.00 sec)MySQL(和PHP搭配之最佳组合)> explain select * from t ignore index(idx_t_mc) where id=1 or mc='1'\G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t         type: ALLpossible_keys: Prima(最完善的虚拟主机管理系统)RY          key: NULL      key_len: NULL          ref: NULL         rows: 10        Extra: Using where1 row in set (0.00 sec)
key_len
key_len列显示MySQL(和PHP搭配之最佳组合)决定使用的键长度。如果键是NULL,则长度为NULL。注意通过key_len值我们可以确定MySQL(和PHP搭配之最佳组合)将实际使用一个多部关键字的几个部分。

ref
ref列显示使用哪个列或常数与key一起从表中选择行。

rows
rows列显示MySQL(和PHP搭配之最佳组合)认为它执行查询时必须检查的行数。

Extra
该列包含MySQL(和PHP搭配之最佳组合)解决查询的详细信息。下面解释了该列可以显示的不同的文本字符串:

Distinct
MySQL(和PHP搭配之最佳组合)发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Not exists
MySQL(和PHP搭配之最佳组合)能够对查询进行LEFT JIN优化,发现1个匹配LEFT JIN标准的行后,不再为前面的的行组合在该表内检查更多的行。

当使用EXTENDED关键字时,EXPLAIN产生附加信息,可以用SHOW WARNINGS浏览。该信息显示优化器限定SELECT语句中的表和列名,重写并且执行优化规则后SELECT语句是什么样子,并且还可能包括优化过程的其它注解。

上一页  1 2 3 4 5 6 7  下一页

Tags:MySQL 数据库 优化

编辑录入:coldstar [复制链接] [打 印]
赞助商链接