作为开发者必须掌握的mysql操作sql语句优化-showprocesslistandexplain(四)

2014-11-24 10:18:28 · 作者: · 浏览: 1
---------+---------+---------+-------+------+-------------+
  • 2 rows in set (0.03 sec)
  • 4.DERIVED:

    当子查询是from子句时,其select_type为DERIVED。

    1. mysql> explain select * from (select order_id from t_order where order_id=100) a;
    2. +----+-------------+------------+--------+---------------+---------+---------+------+------+-------------+
    3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    4. +----+-------------+------------+--------+---------------+---------+---------+------+------+-------------+
    5. | 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | |
    6. | 2 | DERIVED | t_order | const | PRIMARY | PRIMARY | 4 | | 1 | Using index |
    7. +----+-------------+------------+--------+---------------+---------+---------+------+------+-------------+
    8. 2 rows in set (0.03 sec)

    二.type的说明

    1.system,const

    见上面4.DERIVED的例子。其中第一行的type就是为system,第二行是const,这两种联接类型是最快的。

    2.eq_ref

    在t_order表中的order_id是主键,t_order_ext表中的order_id也是主键,该表可以认为是订单表的补充信息表,他们的关系是1对1,在下面的例子中可以看到b表的连接类型是eq_ref,这是极快的联接类型。

     
       
    1. mysql> explain select * from t_order a,t_order_ext b where a.order_id=b.order_id;
    2. +----+-------------+-------+--------+---------------+---------+---------+-----------------+------+-------------+
    3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    4. +----+-------------+-------+--------+---------------+---------+---------+-----------------+------+-------------+
    5. | 1 | SIMPLE | b | ALL | order_id | NULL | NULL | NULL | 1 | |
    6. | 1 | SIMPLE | a | eq_ref | PRIMARY | PRIMARY | 4 | test.b.order_id | 1 | Using where |
    7. +----+-------------+-------+--------+---------------+---------+---------+-----------------+------+-------------+
    8. 2 rows in set (0.00 sec)

    3.ref

    下面的例子在上面的例子上略作了修改,加上了条件。此时b表的联接类型变成了ref。因为所有与a表中order_id=100的匹配记录都将会从b表获取。这是比较常见的联接类型。

     
       
    1. mysql> explain select * from t_order a,t_order_ext b where a.order_id=b.order_id and a.order_id=100;
    2. +----+-------------+-------+-------+---------------+----------+---------+-------+------+-------+
    3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    4. +----+-------------+-------+-------+---------------+----------+---------+-------+------+-------+
    5. | 1 | SIMPLE | a | const | PRIMARY | PRIMARY | 4 | const | 1 | |
    6. | 1 | SIMPLE | b | ref | order_id | order_id | 4 | const | 1 | |
    7. +----+-------------+-------+-------+---------------+----------+---------+-------+------+-------+
    8. 2 rows in set (0.00 sec)

    4.ref_or_null

    user_id字段是一个可以为空的字段,并对该字段创建了一个索引。在下面的查询中可以看到联接类型为ref_or_null,这是mysql为含有null的字段专门做的处理。在我们的表设计中应当尽量避免索引字段为NULL,因为这会额外的耗费mysql的处理时间来做优化。

     
       
    1. mysql> explain select * from t_order where user_id=100 or user_id is null;
    2. +----+-------------+---------+-------------+---------------+---------+---------+-------+-------+-------------+
    3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    4. +----+-------------+---------+-------------+---------------+---------+---------+-------+-------+-------------+
    5. | 1 | SIMPLE | t_order | ref_or_null | user_id | user_id | 5 | const | 50325 | Using where |
    6. +----+-------------+---------+-------------+---------------+---------+---------+-------+-------+-------------+
    7. 1 row in set (0.00 sec)

    5.index_merge

    经常出现在使用一张表中的多个索引时。mysql会将多个索引合并在一起,如下例:

     
       
    1. mysql> explain select * from t_order where order_id=100 or user