Mysql查询优化外键

时间:2013-02-18 05:34:46

标签: mysql optimization join foreign-keys

我有一个主表和一个带有一个外键的子表。当我在这两个表之间加入并使用explain语句来分析性能时

  1. 我得到的解释输出为“Type = ALL”,这被认为是性能最差的。如何提高此联接的效果。

  2. 解释输出只显示“possible_keys:cid_index”而不是key和keylength

  3. 这是一个测试用例

     CREATE TABLE `master` (
      `mid` bigint(20) NOT NULL AUTO_INCREMENT,
      `mname` varchar(20) NOT NULL,
      PRIMARY KEY (`mid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
    
    
    select * from master;
    +-----+-------+
    | mid | mname |
    +-----+-------+
    |   1 | one   |
    |   2 | two   |
    +-----+-------+
    2 rows in set (0.25 sec)
    
    
     CREATE TABLE `child` (
      `cid` bigint(20) NOT NULL AUTO_INCREMENT,
      `cname` varchar(10) NOT NULL,
      `Ccid` bigint(20) DEFAULT NULL,
      PRIMARY KEY (`cid`),
      KEY `cid_index` (`Ccid`),
      CONSTRAINT `new_fk_constraint` FOREIGN KEY (`Ccid`) REFERENCES `master` (`mid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
    
    
    
     select * from child;
    +-----+-------+------+
    | cid | cname | Ccid |
    +-----+-------+------+
    |   1 | Cone  |    1 |
    |   2 | ctwo  |    2 |
    +-----+-------+------+
    2 rows in set (0.12 sec)
    
    
    
    explain select m.*,c.* from master m join child c on  m.mid=c.Ccid \G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: m
             type: ALL
    possible_keys: PRIMARY
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 2
            Extra:
    *************************** 2. row ***************************
               id: 1
      select_type: SIMPLE
            table: c
             type: ALL
    possible_keys: cid_index
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 2
            Extra: Using where; Using join buffer
    2 rows in set (0.23 sec)
    

1 个答案:

答案 0 :(得分:3)

如果表太小,过滤不多,性能可能不如预期。通常,如果where子句过滤超过x%(大约30%),则整个表扫描将更有效。请查看On mysql performance

此外,您可以尝试强制索引并检查索引是否正在使用

explain select m.*,c.* 
from master m 
join child c force index(Ccid) 
on  m.mid=c.Ccid