索引加快速率
select * from t_table where b > 30 and c < 50
可能用到哪些索引?
- A. idx_a(a)
- B. idx_b(b)
- C. idx_a_b(a, b)
小实验
创建表 t_test
,其中有 id, col1, col2, name
四列,id
列为 PK,col1、col2
是 int,name
是 varchar。
填充数据
@SpringBootTest
class DemoApplicationTests {
@Autowired
private TestServiceImpl testService;
@Test
void contextLoads() {
ArrayList<com.engure.filltable.pojo.Test> list = new ArrayList<>();
int index = 0;
// 准备插入一百万条数据
for (int i = 0; i < 1000; i++) {
list.clear();
for (int j = 0; j < 1000; j++) {
list.add(new com.engure.filltable.pojo.Test(index++, i, j, index + "-" + i + "-" + j));
}
testService.saveBatch(list);
}
}
}
(插入到 86.5w 行的时候停止插入,因为已经够用了~~~)
explain 查看索引使用情况
在列上建立索引,使用 explain 分析查询语句,尝试从结果推出原因。
在 col1 上建立索引
-- col1 上创建普通索引
-- alter table t_test add index index_col1(col1);
---------------------
-- 1. 没有使用索引。全表扫描,猜测查询的数据太多,使用索引效率不高
explain select * from t_test where col1 > 30;
-- 2. 使用索引查询
explain select * from t_test where col1 > 30 and col1 < 40;
-- 3. 索引覆盖,使用索引
explain select id,col1 from t_test where col1 > 10;
-- 4. 用到 col1 的索引
explain select * from t_test where col1 > 850 and col2 < 2; -- 选 850 的原因是数据库的 col1 列的范围是 0-864,>850 的数据较少,可以用到索引
-- 5. 没有用到 col1 的索引。col1 > 500 范围太大
explain select * from t_test where col1 > 500 and col2 < 50;
比较:
-
1.
和2.
比较,2.
是查询代价小,使用 range 查询,使用索引 -
3.
使用索引覆盖,即直接在索引结构中查询,不会表 -
4.
与5.
比较结果不同,说明5.
中使用索引代价太大。(回表查 col2 和其他)
建立联合索引 (col1, col2)
loading...
参考文章
沉舟侧畔千帆过,病树前头万木春。