根据我对多列索引的理解,它们仅在您从左侧开始使用列而不跳过任何列时才有用。例如,如果您有(a, b, c)
的索引,则可以在a
,a, b
或a, 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会收集一些关于索引中所有列的额外信息,但如果这是真的 - 是否可以直接看到它?)
答案 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 index
为type
且index
为Extra
,则仍表示正在扫描整个索引:
索引连接类型与ALL相同,但扫描索引树除外。
对于实际使用索引前缀的Using index
查找,解释如下:
MAX