{"id":4420,"date":"2013-04-08T19:07:01","date_gmt":"2013-04-08T11:07:01","guid":{"rendered":"http:\/\/www.orczhou.com\/?p=4420"},"modified":"2013-04-08T19:13:12","modified_gmt":"2013-04-08T11:13:12","slug":"how-mysql-choose-index-in-a-join","status":"publish","type":"post","link":"https:\/\/www.orczhou.com\/index.php\/2013\/04\/how-mysql-choose-index-in-a-join\/","title":{"rendered":"\u6848\u4f8b\uff1aMySQL\u4f18\u5316\u5668\u5982\u4f55\u9009\u62e9\u7d22\u5f15\u548cJOIN\u987a\u5e8f"},"content":{"rendered":"<p>\u672c\u6587\u901a\u8fc7\u4e00\u4e2a\u6848\u4f8b\u6765\u770b\u770bMySQL\u4f18\u5316\u5668\u5982\u4f55\u9009\u62e9\u7d22\u5f15\u548cJOIN\u987a\u5e8f\u3002\u8868\u7ed3\u6784\u548c\u6570\u636e\u51c6\u5907\u53c2\u8003\u672c\u6587\u6700\u540e\u90e8\u5206&#8221;\u6d4b\u8bd5\u73af\u5883&#8221;\u3002\u8fd9\u91cc\u4e3b\u8981\u4ecb\u7ecdMySQL\u4f18\u5316\u5668\u7684\u4e3b\u8981\u6267\u884c\u6d41\u7a0b\uff0c\u800c\u4e0d\u662f\u4ecb\u7ecd\u4e00\u4e2a\u4f18\u5316\u5668\u7684\u5404\u4e2a\u7ec4\u4ef6(\u8fd9\u662f\u53e6\u4e00\u4e2a\u8bdd\u9898)\u3002<\/p>\n\n<p>\u6211\u4eec\u77e5\u9053\uff0cMySQL\u4f18\u5316\u5668\u53ea\u6709\u4e24\u4e2a\u81ea\u7531\u5ea6\uff1a\u987a\u5e8f\u9009\u62e9\uff1b\u5355\u8868\u8bbf\u95ee\u65b9\u5f0f\uff1b\u8fd9\u91cc\u5c06\u8be6\u7ec6\u5256\u6790\u4e0b\u9762\u7684SQL\uff0c\u770b\u770bMySQL\u4f18\u5316\u5668\u5982\u4f55\u505a\u51fa\u6bcf\u4e00\u6b65\u7684\u9009\u62e9\u3002<\/p>\n<pre><blockquote>explain \r\nselect * \r\nfrom \r\n  employee as A,department as B \r\nwhere \r\n      A.LastName = 'zhou' \r\n  and B.DepartmentID = A.DepartmentID \r\n  and B.DepartmentName = 'TBX';<\/blockquote><\/pre>\n<h3>1. \u53ef\u80fd\u7684\u9009\u62e9<\/h3>\n<p>\u8fd9\u91cc\u770b\u5230JOIN\u7684\u987a\u5e8f\u53ef\u4ee5\u662fA|B\u6216\u8005B|A\uff0c\u5355\u8868\u8bbf\u95ee\u65b9\u5f0f\u4e5f\u6709\u591a\u79cd\uff0c\u5bf9\u4e8eA\u8868\u53ef\u4ee5\u9009\u62e9\uff1a\u5168\u8868\u626b\u63cf\u548c\u7d22\u5f15`IND_L_D`(A.LastName = &#8216;zhou&#8217;)\u6216\u8005`IND_DID`(B.DepartmentID = A.DepartmentID)\u3002\u5bf9\u4e8eB\u4e5f\u6709\u4e09\u4e2a\u9009\u62e9\uff1a\u5168\u8868\u626b\u63cf\u3001\u7d22\u5f15IND_D\u3001IND_DN\u3002<\/p>\n<h3>2. MySQL\u4f18\u5316\u5668\u5982\u4f55\u505a<\/h3>\n<h4>2.1 \u6982\u8ff0<\/h4>\n<p>MySQL\u4f18\u5316\u5668\u4e3b\u8981\u5de5\u4f5c\u5305\u62ec\u4ee5\u4e0b\u51e0\u90e8\u5206\uff1aQuery Rewrite(\u5305\u62ecOuter Join\u8f6c\u6362\u7b49)\u3001const table detection\u3001range analysis\u3001JOIN optimization(\u987a\u5e8f\u548c\u8bbf\u95ee\u65b9\u5f0f\u9009\u62e9)\u3001plan refinement\u3002\u8fd9\u4e2a\u6848\u4f8b\u4ecerange analysis\u5f00\u59cb\u3002<\/p>\n<h4>2.2 range analysis<\/h4>\n<p>\u8fd9\u90e8\u5206\u5305\u62ec\u6240\u6709Range\u548cindex merge\u6210\u672c\u8bc4\u4f30(<a href=\"http:\/\/www.orczhou.com\/index.php\/2012\/11\/mysql-source-code-range-optimize-data-structure\/\" target=\"_blank\">\u53c2\u80031<\/a> <a href=\"http:\/\/www.orczhou.com\/index.php\/2012\/12\/mysql-source-code-optimizer-range-and-ref\/\" target=\"_blank\">\u53c2\u80032<\/a>)\u3002\u8fd9\u91cc\uff0c\u7b49\u503c\u8868\u8fbe\u5f0f\u4e5f\u662f\u4e00\u4e2arange\uff0c\u6240\u4ee5\u8fd9\u91cc\u4f1a\u8bc4\u4f30\u5176\u6210\u672c\uff0c\u8ba1\u7b97\u51fafound records(\u8868\u793a\u5bf9\u5e94\u7684\u7b49\u503c\u8868\u8fbe\u5f0f\uff0c\u5927\u6982\u4f1a\u9009\u62e9\u51fa\u591a\u5c11\u6761\u8bb0\u5f55)\u3002<\/p>\n<p>\u672c\u6848\u4f8b\u4e2d\uff0crange analysis\u4f1a\u9488\u5bf9A\u8868\u7684\u6761\u4ef6A.LastName = &#8216;zhou&#8217;\u548cB\u8868\u7684B.DepartmentName = &#8216;TBX&#8217;\u5206\u522b\u505a\u5206\u6790\u3002\u5176\u4e2d\uff1a<!--more--><\/p>\n<pre><blockquote>\u8868A A.LastName = 'zhou' found records: 51\r\n\u8868B B.DepartmentName = 'TBX' found records: 1<\/blockquote><\/pre>\n<p>\u8fd9\u4e24\u4e2a\u6761\u4ef6\u90fd\u4e0d\u662frange\uff0c\u4f46\u662f\u8fd9\u91cc\u8ba1\u7b97\u7684\u503c\u4ecd\u7136\u4f1a\u5b58\u50a8\uff0c\u5728\u540e\u9762\u7684ref\u8bbf\u95ee\u65b9\u5f0f\u8bc4\u4f30\u7684\u65f6\u5019\u4f7f\u7528\u3002\u8fd9\u91cc\u7684\u503c\u662f\u6839\u636erecords_in_range\u63a5\u53e3\u8fd4\u56de\uff0c\u800c\u5bf9\u4e8eInnoDB\u6bcf\u6b21\u8c03\u7528\u8fd9\u4e2a\u51fd\u6570\u90fd\u4f1a\u8fdb\u884c\u4e00\u6b21\u7d22\u5f15\u9875\u7684\u91c7\u6837\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u6d88\u8017\u6027\u80fd\u7684\u64cd\u4f5c\uff0c\u5bf9\u4e8e\u5f88\u591a\u5176\u4ed6\u7684\u5173\u7cfb\u6570\u636e\u5e93\u662f\u4f7f\u7528&#8221;\u76f4\u65b9\u56fe&#8221;\u7684\u7edf\u8ba1\u6570\u636e\u6765\u907f\u514d\u8fd9\u6b21\u64cd\u4f5c(\u76f8\u4fe1MariaDB\u540e\u7eed\u7248\u672c\u4e5f\u5c06\u5b9e\u73b0\u76f4\u65b9\u56fe\u7edf\u8ba1\u4fe1\u606f)\u3002<\/p>\n<h4>2.3 \u987a\u5e8f\u548c\u8bbf\u95ee\u65b9\u5f0f\u7684\u9009\u62e9\uff1a\u7a77\u4e3e<\/h4>\n<p>MySQL\u901a\u8fc7\u679a\u4e3e\u6240\u6709\u7684<a href=\"http:\/\/en.wikipedia.org\/wiki\/Join_(SQL)#Implementation\" target=\"_blank\">left-deep\u6811<\/a>(\u4e5f\u53ef\u4ee5\u8bf4\u6240\u6709\u7684left-deep\u6811\u5c31\u662f\u6574\u4e2aMySQL\u4f18\u5316\u5668\u7684\u641c\u7d22\u7a7a\u95f4)\uff0c\u6765\u627e\u5230\u6700\u4f18\u7684\u6267\u884c\u987a\u5e8f\u548c\u8bbf\u95ee\u65b9\u5f0f\u3002<\/p>\n<h5>2.3.1 \u6392\u5e8f<\/h5>\n<p>\u4f18\u5316\u5668\u5148\u6839\u636efound records\u5bf9\u6240\u6709\u8868\u8fdb\u884c\u4e00\u4e2a\u6392\u5e8f\uff0c\u8bb0\u5f55\u5c11\u7684\u653e\u524d\u9762\u3002\u6240\u4ee5\uff0c\u8fd9\u91cc\u987a\u5e8f\u662fB\u3001A\u3002<\/p>\n<h5>2.3.2 greedy search<\/h5>\n<p>\u5f53\u8868\u7684\u6570\u91cf\u8f83\u5c11(\u5c11\u4e8esearch_depth\uff0c\u9ed8\u8ba4\u662f63)\u7684\u65f6\u5019\uff0c\u8fd9\u91cc\u76f4\u63a5\u8715\u5316\u4e3a\u4e00\u4e2a\u7a77\u4e3e\u641c\u7d22\uff0c\u4f18\u5316\u5668\u5c06\u7a77\u4e3e\u6240\u6709\u7684left-deep\u6811\u627e\u5230\u6700\u4f18\u7684\u6267\u884c\u8ba1\u5212\u3002\u53e6\u5916\uff0c\u4f18\u5316\u5668\u4e3a\u4e86\u51cf\u5c11\u56e0\u4e3a\u641c\u7d22\u7a7a\u95f4\u5e9e\u5927\u5e26\u6765\u5de8\u5927\u7684\u7a77\u4e3e\u6d88\u8017\uff0c\u6240\u4ee5\u4f7f\u7528\u4e86\u4e00\u4e2a&#8221;\u5077\u61d2&#8221;\u7684\u53c2\u6570prune_level(\u9ed8\u8ba4\u6253\u5f00)\uff0c\u5177\u4f53\u5982\u4f55&#8221;\u5077\u61d2&#8221;\uff0c\u53ef\u4ee5\u53c2\u8003<a href=\"http:\/\/www.orczhou.com\/index.php\/2012\/12\/mysql-join-order-complex-or-not\/\" target=\"_blank\">JOIN\u987a\u5e8f\u9009\u62e9\u7684\u590d\u6742\u5ea6<\/a>\u3002\u4e0d\u8fc7\u81f3\u5c11\u9700\u8981\u6709\u4e09\u4e2a\u8868\u4ee5\u4e0a\u7684\u5173\u8054\u624d\u4f1a\u6709&#8221;\u5077\u61d2&#8221;\uff0c\u6240\u4ee5\u672c\u6848\u4f8b\u4e0d\u9002\u7528\u3002<\/p>\n<h5>2.3.3 \u7a77\u4e3e<\/h5>\n<p>JOIN\u7684\u7b2c\u4e00\u4e2a\u8868\u53ef\u4ee5\u662f\uff1aA\u6216\u8005B\uff1b\u5982\u679c\u7b2c\u4e00\u4e2a\u8868\u9009\u62e9\u4e86A\uff0c\u7b2c\u4e8c\u4e2a\u8868\u53ef\u4ee5\u9009\u62e9B\uff1b\u5982\u679c\u7b2c\u4e00\u4e2a\u8868\u9009\u62e9\u4e86B\uff0c\u7b2c\u4e8c\u4e2a\u8868\u53ef\u4ee5\u9009\u62e9A\uff1b<\/p>\n<p>\u56e0\u4e3a\u524d\u9762\u7684\u6392\u5e8f\uff0cB\u8868\u7684found records\u66f4\u5c11\uff0c\u6240\u4ee5JOIN\u987a\u5e8f\u7a77\u4e3e\u65f6\u7684\u7b2c\u4e00\u4e2a\u8868\u5148\u9009\u62e9B(\u8fd9\u4e2a\u662f\u6709\u8bb2\u7a76\u7684)\u3002<\/p>\n<pre><blockquote><span style=\"color:red;\">(*) \u9009\u62e9\u7b2c\u4e00\u4e2aJOIN\u7684\u8868\u4e3aB<\/span>\r\n  <span style=\"color:blue;\">(**) \u786e\u5b9aB\u8868\u7684\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n    \u56e0\u4e3aB\u8868\u4e3a\u7b2c\u4e00\u4e2a\u8868\uff0c\u6240\u4ee5\u65e0\u6cd5\u4f7f\u7528\u7d22\u5f15IND_D(B.DepartmentID = A.DepartmentID)\uff0c\u800c\u53ea\u80fd\u4f7f\u7528IND_DN(B.DepartmentName = 'TBX')\r\n      \u4f7f\u7528IND_DN\u7d22\u5f15\u7684\u6210\u672c\u8ba1\u7b97\uff1a1.2\uff1b\u5176\u4e2dIO\u6210\u672c\u4e3a1\u3002\r\n      \u662f\u5426\u4f7f\u7528\u5168\u8868\u626b\u63cf\uff1a\u8fd9\u91cc\u4f1a\u6bd4\u8f83\u4f7f\u7528\u7d22\u5f15\u7684IO\u6210\u672c\u548c\u5168\u8868\u626b\u63cf\u7684IO\u6210\u672c\uff0c\u524d\u8005\u4e3a1\uff0c\u540e\u8005\u4e3a2\uff1b\u6240\u4ee5\u5ffd\u7565\u5168\u8868\u626b\u63cf\r\n    \u6240\u4ee5\uff0cB\u8868\u7684\u8bbf\u95ee\u65b9\u5f0fref\uff0c\u4f7f\u7528\u7d22\u5f15IND_D\r\n\r\n  <span style=\"color:blue;\">(**) \u4ece\u5269\u4f59\u7684\u8868\u4e2d\u7a77\u4e3e\u9009\u51fa\u7b2c\u4e8c\u4e2aJOIN\u7684\u8868\uff0c\u8fd9\u91cc\u5269\u4f59\u7684\u8868\u4e3a\uff1aA<\/span>\r\n  <span style=\"color:blue;\">(**) \u5c06A\u8868\u52a0\u5165JOIN\uff0c\u5e76\u786e\u5b9a\u5176\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n    \u53ef\u4ee5\u4f7f\u7528\u7684\u7d22\u5f15\u4e3a\uff1a`IND_L_D`(A.LastName = 'zhou')\u6216\u8005`IND_DID`(B.DepartmentID = A.DepartmentID)\r\n    \u4f9d\u6b21\u8ba1\u7b97\u4f7f\u7528\u7d22\u5f15IND_L_D\u3001IND_DID\u7684\u6210\u672c\uff1a\r\n    <span style=\"color:green;\">(***) IND_L_D A.LastName = 'zhou'<\/span>\r\n          \u5728range analysis\u9636\u6bb5\u7ed9\u51fa\u4e86A.LastName = 'zhou'\u5bf9\u5e94\u7684\u8bb0\u5f55\u7ea6\u4e3a\uff1a51\u3002\r\n          \u6240\u4ee5\uff0c\u8ba1\u7b97IO\u6210\u672c\u4e3a\uff1a51\uff1bref\u505aIO\u6210\u672c\u8ba1\u7b97\u65f6\u4f1a\u505a\u4e00\u6b21\u4fee\u6b63\uff0c\u5c06\u5176\u4fee\u6b63\u4e3aworst_seek(<a href=\"http:\/\/www.orczhou.com\/index.php\/2012\/12\/mysql-s\r\nource-code-optimizer-range-and-ref\/#23_IO_COST\" target=\"_blank\">\u53c2\u8003<\/a>)\r\n          \u4fee\u6b63\u540eIO\u6210\u672c\u4e3a\uff1a15\uff0c\u603b\u6210\u672c\u4e3a\uff1a25.2\r\n    <span style=\"color:green;\">(***) IND_DID B.DepartmentID = A.DepartmentID<\/span>\r\n          \u8fd9\u662f\u4e00\u4e2a\u9700\u8981\u77e5\u9053\u524d\u9762\u8868\u7684\u7ed3\u679c\uff0c\u624d\u80fd\u8ba1\u7b97\u7684\u6210\u672c\u3002\u6240\u4ee5range analysis\u662f\u65e0\u6cd5\u5206\u6790\u7684\r\n          \u8fd9\u91cc\uff0c\u6211\u4eec\u770b\u5230\u524d\u9762\u8868\u4e3aB\uff0cfound_record\u662f1\uff0c\u6240\u4ee5A.DepartmentID\u53ea\u9700\u8981\u5bf9\u5e94\u4e00\u6761\u8bb0\u5f55\u5c31\u53ef\u4ee5\u4e86\r\n          \u56e0\u4e3a\u5177\u4f53\u53d6\u503c\u4e0d\u77e5\u9053\uff0c\u4e5f\u6ca1\u6709\u76f4\u65b9\u56fe\uff0c\u6240\u4ee5\u53ea\u80fd\u7b80\u5355\u4f9d\u636e\u7d22\u5f15\u7edf\u8ba1\u4fe1\u606f\u6765\u8ba1\u7b97\uff1a\r\n            \u7d22\u5f15IND_DID\u7684\u5217A.DepartmentID\u7684Cardinality\u4e3a1349\uff0c\u5168\u8868\u8bb0\u5f55\u6570\u4e3a1349\r\n            \u6240\u4ee5\uff0c\u6bcf\u4e00\u4e2a\u503c\u5bf9\u5e94\u4e00\u6761\u8bb0\u5f55\uff0c\u800c\u524d\u9762\u8868B\u53ea\u6709\u4e00\u6761\u8bb0\u5f55\uff0c\u6240\u4ee5\u8fd9\u91cc\u7684found_record\u8ba1\u7b97\u4e3a1*1 = 1\r\n            \u6240\u4ee5IO\u6210\u672c\u4e3a\uff1a1\uff0c\u603b\u6210\u672c\u4e3a1.2\r\n    <span style=\"color:green;\">(***) IND_L_D\u6210\u672c\u4e3a25.2\uff1bIND_DID\u6210\u672c\u4e3a1.2\uff0c\u6240\u4ee5\u9009\u62e9\u540e\u8005\u4e3a\u5f53\u524d\u8868\u7684\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n  <span style=\"color:blue;\">(**) \u786e\u5b9aA\u4f7f\u7528\u7d22\u5f15IND_DID\uff0c\u8bbf\u95ee\u65b9\u5f0f\u4e3aref<\/span>\r\n  <span style=\"color:blue;\">(**) JOIN\u987a\u5e8fB|A\uff0c\u603b\u6210\u672c\u4e3a\uff1a1.2+1.2 = 2.4<\/span>\r\n\r\n<span style=\"color:red;\">(*) \u9009\u62e9\u7b2c\u4e00\u4e2aJOIN\u7684\u8868\u4e3aA<\/span>\r\n  <span style=\"color:blue;\">(**) \u786e\u5b9aA\u8868\u7684\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n       \u56e0\u4e3aA\u8868\u662f\u7b2c\u4e00\u4e2a\u8868\uff0c\u6240\u4ee5\u65e0\u6cd5\u4f7f\u7528\u7d22\u5f15`IND_DID`(B.DepartmentID = A.DepartmentID)\r\n       \u90a3\u4e48\u53ea\u80fd\u4f7f\u7528\u7d22\u5f15`IND_L_D`(A.LastName = 'zhou')\r\n         \u4f7f\u7528IND_L_D\u7d22\u5f15\u7684\u6210\u672c\u8ba1\u7b97\uff0c\u603b\u6210\u672c\u4e3a25.2\uff1b\u53c2\u8003\u524d\u9762\u8ba1\u7b97\uff1b\r\n  <span style=\"color:blue;\">(**) \u8fd9\u91cc\u8bbf\u95eeA\u8868\u7684\u6210\u672c\u5df2\u7ecf\u662f25.2\uff0c\u6bd4\u4e4b\u524d\u7684\u6700\u4f18\u6210\u672c2.4\u8981\u5927\uff0c\u5ffd\u7565\u8be5\u987a\u5e8f<\/span>\r\n       \u6240\u4ee5\uff0c\u8fd9\u6b21\u7a77\u4e3e\u641c\u7d22\u5230\u6b64\u7ed3\u675f\r\n<\/blockquote><\/pre>\n<p>\u628a\u4e0a\u9762\u7684\u8fc7\u7a0b\u7b80\u5316\u5982\u4e0b\uff1a<\/p>\n<pre><blockquote><span style=\"color:red;\">(*) \u9009\u62e9\u7b2c\u4e00\u4e2aJOIN\u7684\u8868\u4e3aB<\/span>\r\n  <span style=\"color:blue;\">(**) \u786e\u5b9aB\u8868\u7684\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n  <span style=\"color:blue;\">(**) \u4ece\u5269\u4f59\u7684\u8868\u4e2d\u7a77\u4e3e\u9009\u51fa\u7b2c\u4e8c\u4e2aJOIN\u7684\u8868\uff0c\u8fd9\u91cc\u5269\u4f59\u7684\u8868\u4e3a\uff1aA<\/span>\r\n  <span style=\"color:blue;\">(**) \u5c06A\u8868\u52a0\u5165JOIN\uff0c\u5e76\u786e\u5b9a\u5176\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n    <span style=\"color:green;\">(***) IND_L_D A.LastName = 'zhou'<\/span>\r\n    <span style=\"color:green;\">(***) IND_DID B.DepartmentID = A.DepartmentID<\/span>\r\n    <span style=\"color:green;\">(***) IND_L_D\u6210\u672c\u4e3a25.2\uff1bIND_DID\u6210\u672c\u4e3a1.2\uff0c\u6240\u4ee5\u9009\u62e9\u540e\u8005\u4e3a\u5f53\u524d\u8868\u7684\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n  <span style=\"color:blue;\">(**) \u786e\u5b9aA\u4f7f\u7528\u7d22\u5f15IND_DID\uff0c\u8bbf\u95ee\u65b9\u5f0f\u4e3aref<\/span>\r\n  <span style=\"color:blue;\">(**) JOIN\u987a\u5e8fB|A\uff0c\u603b\u6210\u672c\u4e3a\uff1a1.2+1.2 = 2.4<\/span>\r\n\r\n<span style=\"color:red;\">(*) \u9009\u62e9\u7b2c\u4e00\u4e2aJOIN\u7684\u8868\u4e3aA<\/span>\r\n  <span style=\"color:blue;\">(**) \u786e\u5b9aA\u8868\u7684\u8bbf\u95ee\u65b9\u5f0f<\/span>\r\n  <span style=\"color:blue;\">(**) \u8fd9\u91cc\u8bbf\u95eeA\u8868\u7684\u6210\u672c\u5df2\u7ecf\u662f25.2\uff0c\u6bd4\u4e4b\u524d\u7684\u6700\u4f18\u6210\u672c2.4\u8981\u5927\uff0c\u5ffd\u7565\u8be5\u987a\u5e8f<\/span>\r\n<\/blockquote><\/pre>\n<p>\u81f3\u6b64\uff0cMySQL\u4f18\u5316\u5668\u5c31\u786e\u5b9a\u4e86\u6240\u6709\u8868\u7684\u6700\u4f73JOIN\u987a\u5e8f\u548c\u8bbf\u95ee\u65b9\u5f0f\u3002<\/p>\n<h3>3. \u6d4b\u8bd5\u73af\u5883<\/h3>\n<pre><blockquote>MySQL: 5.1.48-debug-log innodb plugin 1.0.9\r\n\r\nCREATE TABLE `department` (\r\n  `DepartmentID` int(11) DEFAULT NULL,\r\n  `DepartmentName` varchar(20) DEFAULT NULL,\r\n  KEY `IND_D` (`DepartmentID`),\r\n  KEY `IND_DN` (`DepartmentName`)\r\n) ENGINE=InnoDB DEFAULT CHARSET=gbk;\r\n\r\nCREATE TABLE `employee` (\r\n  `LastName` varchar(20) DEFAULT NULL,\r\n  `DepartmentID` int(11) DEFAULT NULL,\r\n  KEY `IND_L_D` (`LastName`),\r\n  KEY `IND_DID` (`DepartmentID`)\r\n) ENGINE=InnoDB DEFAULT CHARSET=gbk;\r\n\r\nfor 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\r\nfor 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\r\n\r\n\r\n\r\nfor i in `seq 1 50` ; do mysql -vvv -uroot test -e 'insert into employee values (\"zhou\",27760)'; done\r\nfor i in `seq 1 200` ; do mysql -vvv -uroot test -e 'insert into employee values (repeat(char(65+rand()*58),rand()*20),27760)'; done\r\nfor i in `seq 1 1` ; do mysql -vvv -uroot test -e 'insert into department values (27760,\"TBX\")'; done\r\n\r\nshow index from employee;\r\n+----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+\r\n| Table    | Non_unique | Key_name | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |\r\n+----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+\r\n| employee |          1 | IND_L_D  |            1 | LastName     | A         |        1349 |     NULL | NULL   | YES  | BTREE      |         |\r\n| employee |          1 | IND_DID  |            1 | DepartmentID | A         |        1349 |     NULL | NULL   | YES  | BTREE      |         |\r\n+----------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+\r\n\r\nshow index from department;\r\n+------------+------------+----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+\r\n| Table      | Non_unique | Key_name | Seq_in_index | Column_name    | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |\r\n+------------+------------+----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+\r\n| department |          1 | IND_D    |            1 | DepartmentID   | A         |        1001 |     NULL | NULL   | YES  | BTREE      |         |\r\n| department |          1 | IND_DN   |            1 | DepartmentName | A         |        1001 |     NULL | NULL   | YES  | BTREE      |         |\r\n+------------+------------+----------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+<\/blockquote><\/pre>\n<h3>4. \u6784\u9020\u4e00\u4e2aBad case<\/h3>\n<p>\u56e0\u4e3a\u5173\u8054\u6761\u4ef6\u4e2dMySQL\u4f7f\u7528\u7d22\u5f15\u7edf\u8ba1\u4fe1\u606f\u505a\u6210\u672c\u9884\u4f30\uff0c\u6240\u4ee5\u6570\u636e\u5206\u5e03\u4e0d\u5747\u5300\u7684\u65f6\u5019\uff0c\u5c31\u5bb9\u6613\u505a\u51fa\u9519\u8bef\u7684\u5224\u65ad\u3002\u7b80\u5355\u7684\u6211\u4eec\u6784\u9020\u4e0b\u9762\u7684\u6848\u4f8b\uff1a<\/p>\n<p>\u8868\u548c\u7d22\u5f15\u7ed3\u6784\u4e0d\u53d8\uff0c\u6309\u7167\u4e0b\u9762\u7684\u65b9\u5f0f\u6784\u9020\u6570\u636e\uff1a<\/p>\n<pre><blockquote>\r\nfor i in `seq 1 10000` ; do mysql -uroot test -e 'insert into department values (600000*rand(),repeat(char(65+rand()*58),rand()*20))'; done\r\nfor i in `seq 1 10000` ; do mysql -uroot test -e 'insert into employee values (repeat(char(65+rand()*58),rand()*20),600000*rand())'; done\r\n\r\nfor i in `seq 1 1` ; do mysql -uroot test -e 'insert into employee values (\"zhou\",27760)'; done\r\nfor i in `seq 1 10` ; do mysql -uroot test -e 'insert into department values (27760,\"TBX\")'; done\r\nfor i in `seq 1 1000` ; do mysql -uroot test -e 'insert into department values (27760,repeat(char(65+rand()*58),rand()*20))';\r\ndone<\/blockquote><\/pre>\n<pre><blockquote>explain \r\nselect * \r\nfrom \r\n  employee as A,department as B \r\nwhere \r\n      A.LastName = 'zhou' \r\n  and B.DepartmentID = A.DepartmentID \r\n  and B.DepartmentName = 'TBX';\r\n+----+-------------+-------+------+-----------------+---------+---------+---------------------+------+-------------+\r\n| id | select_type | table | type | possible_keys   | key     | key_len | ref                 | rows | Extra       |\r\n+----+-------------+-------+------+-----------------+---------+---------+---------------------+------+-------------+\r\n|  1 | SIMPLE      | A     | ref  | IND_L_D,IND_DID | IND_L_D | 43      | const               |    1 | Using where |\r\n|  1 | SIMPLE      | B     | ref  | IND_D,IND_DN    | IND_D   | 5       | test.A.DepartmentID |    1 | Using where |\r\n+----+-------------+-------+------+-----------------+---------+---------+---------------------+------+-------------+<\/blockquote><\/pre>\n<p>\u53ef\u4ee5\u770b\u5230\u8fd9\u91cc\uff0cMySQL\u6267\u884c\u8ba1\u5212\u5bf9\u8868department\u4f7f\u7528\u4e86\u7d22\u5f15IND_D\uff0c\u90a3\u4e48A\u8868\u547d\u4e2d\u4e00\u6761\u8bb0\u5f55\u4e3a(zhou,27760)\uff1b\u6839\u636eB.DepartmentID=27760\u5c06\u8fd4\u56de1010\u6761\u8bb0\u5f55\uff0c\u7136\u540e\u6839\u636e\u6761\u4ef6DepartmentName = &#8216;TBX&#8217;\u8fdb\u884c\u8fc7\u6ee4\u3002<\/p>\n<p>\u8fd9\u91cc\u53ef\u4ee5\u770b\u5230\u5982\u679cB\u8868\u9009\u62e9\u7d22\u5f15IND_DN\uff0c\u6548\u679c\u8981\u66f4\u597d\uff0c\u56e0\u4e3aDepartmentName = &#8216;TBX&#8217;\u4ec5\u4ec5\u8fd4\u56de10\u6761\u8bb0\u5f55\uff0c\u518d\u6839\u636e\u6761\u4ef6A.DepartmentID=B.DepartmentID\u8fc7\u6ee4\u4e4b\u3002<\/p>\n<p>\u8fd9\u4e2a\u6848\u4f8b\u4e2d\u56e0\u4e3a\u6570\u636e\u91cf\u5f88\u5c0f\uff0c\u6027\u80fd\u8fd8\u76f8\u5dee\u4e0d\u5927\uff0c\u4f46\u5982\u679c\u751f\u4ea7\u73af\u5883\u4e2d\u6570\u636e\u662f\u5343\u4e07\u6216\u8005\u4ebf\u7ea7\u522b\u7684\u65f6\u5019\u6027\u80fd\u5c31\u4f1a\u5dee\u975e\u5e38\u975e\u5e38\u975e\u5e38\u5927\u3002\u901a\u8fc7\u7b80\u5355\u7684Hint\u53ef\u4ee5\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u901a\u8fc7\u4e00\u4e2a\u6848\u4f8b\u6765\u770b\u770bMySQL\u4f18\u5316\u5668\u5982\u4f55\u9009\u62e9\u7d22\u5f15\u548cJOIN\u987a\u5e8f\u3002\u8868\u7ed3\u6784\u548c\u6570\u636e\u51c6\u5907\u53c2\u8003\u672c\u6587\u6700\u540e\u90e8\u5206&#8221;\u6d4b\u8bd5\u73af\u5883&#8221;\u3002\u8fd9\u91cc\u4e3b\u8981\u4ecb\u7ecdMySQL\u4f18\u5316\u5668\u7684\u4e3b\u8981\u6267\u884c\u6d41\u7a0b\uff0c\u800c\u4e0d\u662f\u4ecb\u7ecd\u4e00\u4e2a\u4f18\u5316\u5668\u7684\u5404\u4e2a\u7ec4\u4ef6(\u8fd9\u662f\u53e6\u4e00\u4e2a\u8bdd\u9898)\u3002 \u6211\u4eec\u77e5\u9053\uff0cMySQL\u4f18\u5316\u5668\u53ea\u6709\u4e24\u4e2a\u81ea\u7531\u5ea6\uff1a\u987a\u5e8f\u9009\u62e9\uff1b\u5355\u8868\u8bbf\u95ee\u65b9\u5f0f\uff1b\u8fd9\u91cc\u5c06\u8be6\u7ec6\u5256\u6790\u4e0b\u9762\u7684SQL\uff0c\u770b\u770bMySQL\u4f18\u5316\u5668\u5982\u4f55\u505a\u51fa\u6bcf\u4e00\u6b65\u7684\u9009\u62e9\u3002 explain select * from employee as A,department as B where A.LastName = &#8216;zhou&#8217; and B.DepartmentID = A.DepartmentID and B.DepartmentName = &#8216;TBX&#8217;; 1. \u53ef\u80fd\u7684\u9009\u62e9 \u8fd9\u91cc\u770b\u5230JOIN\u7684\u987a\u5e8f\u53ef\u4ee5\u662fA|B\u6216\u8005B|A\uff0c\u5355\u8868\u8bbf\u95ee\u65b9\u5f0f\u4e5f\u6709\u591a\u79cd\uff0c\u5bf9\u4e8eA\u8868\u53ef\u4ee5\u9009\u62e9\uff1a\u5168\u8868\u626b\u63cf\u548c\u7d22\u5f15`IND_L_D`(A.LastName = &#8216;zhou&#8217;)\u6216\u8005`IND_DID`(B.DepartmentID = A.DepartmentID)\u3002\u5bf9\u4e8eB\u4e5f\u6709\u4e09\u4e2a\u9009\u62e9\uff1a\u5168\u8868\u626b\u63cf\u3001\u7d22\u5f15IND_D\u3001IND_DN\u3002 2. MySQL\u4f18\u5316\u5668\u5982\u4f55\u505a 2.1 \u6982\u8ff0 MySQL\u4f18\u5316\u5668\u4e3b\u8981\u5de5\u4f5c\u5305\u62ec\u4ee5\u4e0b\u51e0\u90e8\u5206\uff1aQuery Rewrite(\u5305\u62ecOuter Join\u8f6c\u6362\u7b49)\u3001const table detection\u3001range analysis\u3001JOIN optimization(\u987a\u5e8f\u548c\u8bbf\u95ee\u65b9\u5f0f\u9009\u62e9)\u3001plan refinement\u3002\u8fd9\u4e2a\u6848\u4f8b\u4ecerange analysis\u5f00\u59cb\u3002 2.2 range analysis \u8fd9\u90e8\u5206\u5305\u62ec\u6240\u6709Range\u548cindex merge\u6210\u672c\u8bc4\u4f30(\u53c2\u80031 \u53c2\u80032)\u3002\u8fd9\u91cc\uff0c\u7b49\u503c\u8868\u8fbe\u5f0f\u4e5f\u662f\u4e00\u4e2arange\uff0c\u6240\u4ee5\u8fd9\u91cc\u4f1a\u8bc4\u4f30\u5176\u6210\u672c\uff0c\u8ba1\u7b97\u51fafound records(\u8868\u793a\u5bf9\u5e94\u7684\u7b49\u503c\u8868\u8fbe\u5f0f\uff0c\u5927\u6982\u4f1a\u9009\u62e9\u51fa\u591a\u5c11\u6761\u8bb0\u5f55)\u3002 \u672c\u6848\u4f8b\u4e2d\uff0crange analysis\u4f1a\u9488\u5bf9A\u8868\u7684\u6761\u4ef6A.LastName = &#8216;zhou&#8217;\u548cB\u8868\u7684B.DepartmentName = [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_eb_attr":"","inline_featured_image":false,"_tocer_settings":[],"footnotes":""},"categories":[6],"tags":[101,118,102,58],"class_list":["post-4420","post","type-post","status-publish","format-standard","hentry","category-mysql","tag-index","tag-mysql","tag-optimizer","tag-source-code"],"_links":{"self":[{"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/posts\/4420","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/comments?post=4420"}],"version-history":[{"count":24,"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/posts\/4420\/revisions"}],"predecessor-version":[{"id":4450,"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/posts\/4420\/revisions\/4450"}],"wp:attachment":[{"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/media?parent=4420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/categories?post=4420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.orczhou.com\/index.php\/wp-json\/wp\/v2\/tags?post=4420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}