select id,char_name from table_chara where attack_id= 123   or  defend_id= 123
我对attack_id和defend_id分别设置了Normal类型的索引
这样子搞的话是全盘扫描,对吧?照网上的做法,用union all的办法,将上面改成:
select id,char_name from table_chara where attack_id= 123  union all select id,char_name from table_chara where defend_id= 123我通过explain分析,得出下面的结果:
+------+--------------+----------------+------+---------------+-----------+---------+-------+------+----------------+
| id   | select_type  | table          | type | possible_keys | key       | key_len | ref   | rows | Extra          |
+------+--------------+----------------+------+---------------+-----------+---------+-------+------+----------------+
|    1 | PRIMARY      | log_pet_battle | ref  | attack_id     | attack_id | 8       | const |    1 |                |
|    2 | UNION        | log_pet_battle | ref  | defend_id     | defend_id | 9       | const |    4 | Using where    |
| NULL | UNION RESULT | <union1,2>     | ALL  | NULL          | NULL      | NULL    | NULL  | NULL | Using filesort |
+------+--------------+----------------+------+---------------+-----------+---------+-------+------+----------------+
请问这种优化方法正确吗?最后那一行是什么意思呢?

解决方案 »

  1.   

    MySQL5.0以后的版本可以直接对你第一个语句使用合并索引,不需要写成UNION ALL的形式,可能楼主的版本是5.0以前的~
    至于第二条语句,有些错误在里面,这样产生的结果集会有重复的记录,即那些满足attack_id= 123 AND 
    defend_id= 123的行会出现两次(如果绝对不会存在这些行,那么没问题),LZ要么把UNION ALL改成UNION,要么给第二个UNION加一个条件:
    select id,char_name from table_chara where attack_id= 123 
    union all 
    select id,char_name from table_chara where defend_id= 123 AND attack_id!=123
    我推荐第二种改法(这个是《高性能MySQL》里的写法),不需要使用UNION,UNION相对于UNION ALL低效很多~ 
      

  2.   

    将OR语句修改为UNION ALL的写法是优化OR语句的通用法则。
      

  3.   

    explain出来是你想要的 那就是对的