为什么MAX在索引中间的列上工作

时间:2018-01-02 22:56:11

标签: mysql

根据我对多列索引的理解,它们仅在您从左侧开始使用列而不跳过任何列时才有用。例如,如果您有(a, b, c)的索引,则可以在aa, ba, b, c上进行查询。

但今天我发现当在InnoDB表上有一个索引(BTREE)时:

some_varchar, some_bigint, other_varchar

我可以查询:

SELECT MAX(some_bigint) FROM the_table

并且它的计划说:

           id: 1
  select_type: SIMPLE
        table: the_table
         type: index
possible_keys: NULL
          key: index_some_varchar_some_bigint_other_varchar
      key_len: 175
          ref: NULL
         rows: 1
        Extra: Using index

这似乎不同意the docs。自key设置后,它也会造成混淆,但possible_keys不是。

这在实践中如何运作?如果密钥首先由some_varchar排序,(或者它的前缀),MySQL如何从中获取第二列的MAX

(猜测是MySQL会收集一些关于索引中所有列的额外信息,但如果这是真的 - 是否可以直接看到它?)

1 个答案:

答案 0 :(得分:2)

我对索引的理解是正确的,但对<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> </title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" type="text/javascript"></script> </head> <body> <form method="post" action="./StJudes" id="form1"> <div class="aspNetHidden"> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/arN4mVK5SbGdvL+R7WrYMRnz8V5l4JL9V3Mni0wMrfoNV8HdxGgfuGLcsQDI0QcQeB6J8U7mUzXSzGMKyLlJ/aalb0tRLilgRH6mlf+ZTGC8f8NBCIb0Bqhs/nU7dyk10ZeZxyc6US362rQdf2I507YnK8EcAXrTQuUir4mMyh+k06tUlLZeA6NHntT45j7vnUsboHm0wCzhuW9B6Kw9QTgoB5XnbsmLTxsAPmvpNCI7ATtIfX6pF1hf/1WkrkN0tYmKA3MX+Uq2N2gXwnZFx73mxAAbpSFcx7P8kIdNlBze3XwgzCHL9qJRujTxxlnbcnwrw00drXudPbiZvKFL7f2Hnfe0xs+k6WOx962kiF0sHyvNhLBC3o4yqfV3tzdcNpCbt/YlUYJP5LkVJ4k7rmr638IMr021fgYGLhRxff70NKwBNKrkUflk/ZpoY8oMLciB3AZPq4x7ob0WAa7l4HGlWEusMCxsiW0i3/VMFLnS/VtmoJIdcRGrbwjbGNq1EvnCyh32oCvgO/kmzlMVCVOtpZhNR+SBpdQW4dIhkBCCKQHReV8YPK0OF13hEHAekgFuXw5SsTok8dGtLUnDXoy1DOxbe3AV6wpdTzuDvQfsgJYEiV1mUn1k35E4pz4+dLNK7RtjM4nId0jnj6Rpfgpke743BNmwr7prkcbMoBz44Rf3K+Ov2+UlMj3mXYWvREGBmAUWAqvRuHu373uZ6JyjHY0lg7Ui+5fGGkyrBezZFHgoSRu/xmPP9em0myqagVQxKZHXOGHsPwBd2+ZHl5hsC/eO21X3SxGJmoc6PO1Grns5X0oSNv3moG/J+7ZfU6LWJobDZ4cJkMa3KjgB5+ymRm2AjoIQwkwCI9SOAe4g0NLMaOdYCJ/VVgfGEgdgTyN/qM9owibjyXNQEtHH/gpMv1bNZ5jHZzc0LOZEG7KltJ4PMdVyAjwpV3wR9Q1Yz6/YBE0rYYM7+cMcMFgqvkmggMZ/EiCSB/NWcpkl4Ljrs9C6xcF6Rh51W56Ddf2C5ZEIhrE3KCOHDWlr3pj9zF7CIyGVIpwtsTTCQfCL7QjlIw5u2vd4HvlfrdYrErv/ezDXrTMErkQnpfaQRpwi4zLOCZKQ9Qd2SYGaKZsDdN6foV7iBPH5TABi2r8SUUHotDlWD8bYbntUAlTVhJ1e5amY7RgzWNVPhlsTLIfFF5vwQAW0Qg9BSUTKOtx1A5dssTY9iUlVa+gJDjfEohvLcO9Qtym8As+OA2tBCJ/2jQyhGgo+prm1S+MVGTVuItm" /> </div> <div> <table id="cbxlTestInputAmt"> <tr> <td><input id="cbxlTestInputAmt_0" type="checkbox" name="cbxlTestInputAmt$0" value="Choice 1" /><label for="cbxlTestInputAmt_0">Choice 1</label></td><td><input id="cbxlTestInputAmt_8" type="checkbox" name="cbxlTestInputAmt$8" value="Choice 5" /><label for="cbxlTestInputAmt_8">Choice 5</label></td> </tr><tr> <td><input id="cbxlTestInputAmt_1" type="checkbox" name="cbxlTestInputAmt$1" value="Choice 2" /><label for="cbxlTestInputAmt_1">Choice 2</label></td><td><input id="cbxlTestInputAmt_9" type="checkbox" name="cbxlTestInputAmt$9" value="Choice 6" /><label for="cbxlTestInputAmt_9">Choice 6</label></td> </tr><tr> <td><input id="cbxlTestInputAmt_2" type="checkbox" name="cbxlTestInputAmt$2" value="Choice 3" /><label for="cbxlTestInputAmt_2">Choice 3</label></td><td><input id="cbxlTestInputAmt_10" type="checkbox" name="cbxlTestInputAmt$10" value="Choice 7" /><label for="cbxlTestInputAmt_10">Choice 7</label></td> </tr><tr> <td><input id="cbxlTestInputAmt_3" type="checkbox" name="cbxlTestInputAmt$3" value="Choice 4" /><label for="cbxlTestInputAmt_3">Choice 4</label></td><td><input id="cbxlTestInputAmt_11" type="checkbox" name="cbxlTestInputAmt$11" value="Choice 8" /><label for="cbxlTestInputAmt_11">Choice 8</label></td> </tr><tr> </tr> </table> </div> <div class="aspNetHidden"> <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="EAAE48E8" /> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="Sy90TVaOKW0SPZaQc4kBfWFelyOefK2WoFykp7mXwf8t1tCQ1rpzVdnpgLuNxUsSq4LLnzDYvh5HpOvi781XrWO2QN3jsMS0nwr+2o8Qq5CSde1phnI9bO5cNFwJLytC54FG6o/Uv4AbjSKIvZ5hsmWRfu0AtPCuFsgeJXK3nkJI++SHHLuvdqc3dkJYCyzFY8ls6ton28qjRu1LfvTN40WIGxqe+XODIS5UEeFpj3eAbjN4vZnO9rAkE3mGOscT50S201BcFZQNRvzJMEDYe2lXadzzxCWP2P5456Q18+P3A9DPlZheRW6yTNdiUM1HUoZXpMjtR0+8nbnDnCBv4TNcjSdUCKz2hOWuuESysZr5u52LKxZFKQKXFpQVwLjm4GiNRSs03ERpdikPXXMH1Wg1j8SrK5eYkZiGO+DMBciiv3nud//ZiRZeeUcn14Mj" /> </div></form> <script type="text/javascript"> var limit = 5; $(function () { $('#form1').on('change', '[id*="cbxlTestInputAmt"]', function (evt) { if ($('[id*="cbxlTestInputAmt"]:checked').length > limit) { this.checked = false; alert('cannot select more than ' + limit); } }); }); </script> <!-- Visual Studio Browser Link --> <script type="application/json" id="__browserLink_initializationData"> {"appName":"Chrome","requestId":"fc04a78059374a078423b035a01ea2a7"} </script> <script type="text/javascript" src="http://localhost:60326/3217fe137445440cbce21c780fe62311/browserLink" async="async"></script> <!-- End Browser Link --> </body> </html>的含义的理解是错误的。

Using index并不一定意味着通过快速查找访问了该值。它只是意味着没有访问行数据。如果Using indextypeindexExtra,则仍表示正在扫描整个索引:

来自the documentation

  

索引连接类型与ALL相同,但扫描索引树除外。

对于实际使用索引前缀的Using index查找,解释如下:

MAX