【MYSQL】一个关于最左匹配原则的问题

最左匹配原则

最左原则顾名思义就是从最左边开始匹配的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式,其针对的是组合索引(又名联合索引)。

问题

数据库里有四个字段,id,a,b,c,其中id是主键,有两个 联合索引,ab,ac下面几个查询都会用到哪些索引?

  • select * from t where a=xx and b=xx;
  • select * from t where b=xx and c=xx;
  • select * from t where a=xx and b=xx and c==xx;
  • select * from t where a=xx and c=xx and b==xx;
  • select * from t where a=xx and (b=xx or b==xx);

SQL脚本

CREATE TABLE test2 (
  id INT PRIMARY KEY,
  a VARCHAR(255),
  b VARCHAR(255),
  c VARCHAR(255),
  INDEX idx_ab (a, b),
  INDEX idx_ac (a, c)
);

INSERT INTO test2 (id, a, b, c) VALUES
(1, 'Alice', 'Bob', 'Hello, Bob!'),
(2, 'Alice', 'Charlie', 'Hi, Charlie!'),
(3, 'Bob', 'Alice', 'Hey, Alice!'),
(4, 'Bob', 'Charlie', 'Hello, Charlie!'),
(5, 'Charlie', 'Alice', 'Hey, Alice!'),
(6, 'Charlie', 'Bob', 'Hi, Bob!'),
(7, 'Alice', 'David', 'Hello, David!'),
(8, 'Bob', 'Eve', 'Hi, Eve!'),
(9, 'Charlie', 'Frank', 'Hey, Frank!'),
(10, 'David', 'Alice', 'Hi, Alice!'),
(11, 'Eve', 'Bob', 'Hello, Bob!'),
(12, 'Frank', 'Charlie', 'Hi, Charlie!'),
(13, 'Alice', 'George', 'Hey, George!'),
(14, 'Bob', 'Helen', 'Hello, Helen!'),
(15, 'Charlie', 'Ivy', 'Hi, Ivy!'),
(16, 'David', 'Jack', 'Hey, Jack!'),
(17, 'Eve', 'Kate', 'Hi, Kate!'),
(18, 'Frank', 'Lucy', 'Hello, Lucy!'),
(19, 'George', 'Mary', 'Hi, Mary!'),
(20, 'Helen', 'Nancy', 'Hey, Nancy!');

SELECT * FROM test2;

使用explain分析SQL计划

情况1:select * from t where a=xx and b=xx;

EXPLAIN SELECT a FROM test2 WHERE a='Alice' AND b='David';

 符合最左匹配原则,走联合索引idx_ab。

情况2:select * from t where b=xx and c=xx;

EXPLAIN SELECT * FROM test2 WHERE b='George' AND c='Hey, George!'

key为NULL,不符合最左匹配原则,不走索引。

情况3:select * from t where a=xx and b=xx and c==xx;

EXPLAIN SELECT * FROM test2 WHERE a='Alice' AND b='George' AND c='Hey, George!';

同时满足2个索引的最左匹配原则,走了两个索引。type中标识了这是一次index_merge(索引合并),using intersect代表对两边数据求交集

情况4:select * from t where a=xx and c=xx and b==xx;

EXPLAIN SELECT a,b FROM test2 WHERE a='Alice' AND c='Hey, George!' AND b='George';

与abc在sql中的顺序无关,与情况3一样。  

情况5:select * from t where a=xx and (b=xx or b==xx);

EXPLAIN SELECT a FROM test2 WHERE a='Alice' AND (b='David' OR b='George');

 走索引idx_ab

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在MySQL中,最左匹配原则指的是联合索引中只有先确定了前一个(左侧的值)后,才能确定下一个值。当遇到范围查询(如>、<、between、like)时,联合索引中使用范围查询字段后的索引在该条SQL中都不会起作用。这意味着,如果查询条件中有范围查询,那么联合索引只能用到范围查询之前的字段。\[1\] 举个例子,如果有一个联合索引(a,b,c),那么查询语句select * from t where c=1 and a=1 and b=1可以使用最左匹配原则,因为MySQL的优化器会将其优化成索引可以匹配的形式,即select * from t where a=1 and a=1 and c=1。\[2\]所以,最左匹配原则并不适用于范围查找。 #### 引用[.reference_title] - *1* *2* [MYSQL最左匹配原则的原理讲解](https://blog.csdn.net/Andrew_Chenwq/article/details/125242197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Mysql最左匹配原则](https://blog.csdn.net/qq_42410605/article/details/122517756)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值