• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 案例:MySQL優化器如何選擇索引和JOIN順序(2)

    發表于:2013-05-06來源:不祥作者:不詳點擊數: 標簽:MySQL
    (*) 選擇第一個JOIN的表為A (**) 確定A表的訪問方式 因為A表是第一個表,所以無法使用索引`IND_DID`(B.DepartmentID = A.DepartmentID) 那么只能使用索引`IND_L_D`(A.Last

      (*) 選擇第一個JOIN的表為A

      (**) 確定A表的訪問方式

      因為A表是第一個表,所以無法使用索引`IND_DID`(B.DepartmentID = A.DepartmentID)

      那么只能使用索引`IND_L_D`(A.LastName = 'zhou')

      使用IND_L_D索引的成本計算,總成本為25.2;參考前面計算;

      (**) 這里訪問A表的成本已經是25.2,比之前的最優成本2.4要大,忽略該順序

      所以,這次窮舉搜索到此結束

      把上面的過程簡化如下:

      (*) 選擇第一個JOIN的表為B

      (**) 確定B表的訪問方式

      (**) 從剩余的表中窮舉選出第二個JOIN的表,這里剩余的表為:A

      (**) 將A表加入JOIN,并確定其訪問方式

      (***) IND_L_D A.LastName = 'zhou'

      (***) IND_DID B.DepartmentID = A.DepartmentID

      (***) IND_L_D成本為25.2;IND_DID成本為1.2,所以選擇后者為當前表的訪問方式

      (**) 確定A使用索引IND_DID,訪問方式為ref

      (**) JOIN順序B|A,總成本為:1.2+1.2 = 2.4

      (*) 選擇第一個JOIN的表為A

      (**) 確定A表的訪問方式

      (**) 這里訪問A表的成本已經是25.2,比之前的最優成本2.4要大,忽略該順序

      至此,MySQL優化器就確定了所有表的最佳JOIN順序和訪問方式。

      3. 測試環境

      MySQL: 5.1.48-debug-log innodb plugin 1.0.9

      CREATE TABLE `department` (

      `DepartmentID` int(11) DEFAULT NULL,

      `DepartmentName` varchar(20) DEFAULT NULL,

      KEY `IND_D` (`DepartmentID`),

      KEY `IND_DN` (`DepartmentName`)

      ) ENGINE=InnoDB DEFAULT CHARSET=gbk;

      CREATE TABLE `employee` (

      `LastName` varchar(20) DEFAULT NULL,

      `DepartmentID` int(11) DEFAULT NULL,

      KEY `IND_L_D` (`LastName`),

      KEY `IND_DID` (`DepartmentID`)

      ) ENGINE=InnoDB DEFAULT CHARSET=gbk;

      for i in `seq 1 1000` ; do mysql -vvv -uroot test -e 'insert into department values (600000*rand(),repeat(char(65+rand()*58),rand()*20))'; done

      for i in `seq 1 1000` ; do mysql -vvv -uroot test -e 'insert into employee values (repeat(char(65+rand()*58),rand()*20),600000*rand())'; done

      for i in `seq 1 50` ; do mysql -vvv -uroot test -e 'insert into employee values ("zhou",27760)'; done

      for i in `seq 1 200` ; do mysql -vvv -uroot test -e 'insert into employee values (repeat(char(65+rand()*58),rand()*20),27760)'; done

      for i in `seq 1 1` ; do mysql -vvv -uroot test -e 'insert into department values (27760,"TBX")'; done

      show index from employee;

      +----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+

      | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |

      +----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+

      | employee | 1 | IND_L_D | 1 | LastName | A | 1349 | NULL | NULL | YES | BTREE | |

      | employee | 1 | IND_DID | 1 | DepartmentID | A | 1349 | NULL | NULL | YES | BTREE | |

      +----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+

      show index from department;

      +------------+------------+----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+

      | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |

      +------------+------------+----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+

      | department | 1 | IND_D | 1 | DepartmentID | A | 1001 | NULL | NULL | YES | BTREE | |

      | department | 1 | IND_DN | 1 | DepartmentName | A | 1001 | NULL | NULL | YES | BTREE | |

      +------------+------------+----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+

      4. 構造一個Bad case

      因為關聯條件中MySQL使用索引統計信息做成本預估,所以數據分布不均勻的時候,就容易做出錯誤的判斷。簡單的我們構造下面的案例:

      表和索引結構不變,按照下面的方式構造數據:

      for i in `seq 1 10000` ; do mysql -uroot test -e 'insert into department values (600000*rand(),repeat(char(65+rand()*58),rand()*20))'; done

      for i in `seq 1 10000` ; do mysql -uroot test -e 'insert into employee values (repeat(char(65+rand()*58),rand()*20),600000*rand())'; done

      for i in `seq 1 1` ; do mysql -uroot test -e 'insert into employee values ("zhou",27760)'; done

      for i in `seq 1 10` ; do mysql -uroot test -e 'insert into department values (27760,"TBX")'; done

    原文轉自:http://www.orczhou.com/index.php/2013/04/how-mysql-choose-index-in-a-join/

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>