多列主键场景下,单独查询非首列是否需额外创建索引?
这问题问得特别到位,刚好戳中复合索引(包括复合主键索引)最容易被误解的点!
先明确核心规则:复合主键的索引是按你定义的字段顺序构建的——你的主键是(created_at, uuid),所以这个索引的结构是先按created_at排序,在同一个created_at值下再按uuid排序,完全遵循「最左匹配原则」。
两种查询场景的差异
带最左前缀的查询(能用到主键索引)
像你写的SELECT * FROM mytable WHERE created_at > '2018-01-01' AND uuid = 'abc',因为查询条件包含了复合索引的第一个字段created_at,数据库可以先通过索引快速定位到created_at > '2018-01-01'的记录范围,再在这个范围内直接匹配uuid = 'abc',完全能利用主键索引的高效性。仅查询非前缀字段(主键索引无法有效生效)
但如果是SELECT * FROM mytable WHERE uuid = 'abc',情况就完全不同了:由于复合索引是先按created_at排序的,所有uuid = 'abc'的记录会分散在不同的created_at分组里,数据库没办法直接通过主键索引定位到这些记录,只能要么全表扫描,要么遍历整个主键索引逐一比对uuid值,数据量大的时候效率会极低。
结论
这种情况下必须单独为uuid列创建独立索引,才能让仅按uuid查询的语句高效执行。
额外补一句:复合索引的字段顺序直接决定了适用场景——如果你的主键顺序是(uuid, created_at),那单独查uuid就能用索引,但单独查created_at就不行,这点一定要记牢。
内容的提问来源于stack exchange,提问作者grunk

