41 使用 Order By 时能否通过索引排序
是,排序方向一致
- 索引列顺序匹配。
- 排序方向一致。
- 覆盖索引。
42 通过索引排序内部流程是什么?
select name,id from user where name like '%明' order by name;
-
查询优化器判断:若 order by 字段有可用索引且顺序匹配,优先使用索引排序
-
数据获取:
- 覆盖索引:直接通过索引获取所有字段,无需回表 。
- 非覆盖索引:取出排序字段和主键,可能触发回表。
-
排序执行:
- 单路排序:一次性加载所有字段到内存排序(需内存足够)
- 双路排序:分两次扫描磁盘。首次排序后回表取其他字段(内存不足时触发)
-
结果返回:排序后直接输出,减少随机I/O
- 增大 sort_buffer_size 参数的设置
- 增大 max_length_for_sort_date 参数的设置
- 减少 select 后面的查询的字段,禁止使用 select *
43 什么是双路排序和单路排序?
-
单路排序(Single-Pass Sorting)
-
定义:一次性将所有需要排序的字段(包括查询字段和排序字段)加载到内存(sort_buffer)中进行排序,排序完成后直接返回结果。
-
特点:
- 内存充足时效率高。避免磁盘I/O
- 若字段总长度超过 max_length_for_sort_data 默认 1024 字节),则无法使用。
-
-
双路排序(Two-Pass Sorting)
-
定义:分两次扫描数据:
- 第一次:仅加载排序字段和主键到内存排序。
- 第二次:根据排序结果回表查询其他字段,合并后返回结果。
-
特点:
- 内存不足时触发,需写入临时文件并合并排序,增加I/O开销。
- 通过主键回表减少内存占用,但可能因多次I/O降低性能。
-
关键区别:
- 数据加载:单路一次性加载所有字段,双路分两次加载。
- 性能影响:单路依赖内存大小,双路依赖磁盘I/O。
- 触发条件:由 max_length_for_sort_data 参数控制。
优化建议:
- 增大 sort_buffer_size 和 max_length_for_sort_data 以减少双路排序。
- 使用覆盖索引避免回表。
44 group by 分组和order by在索引使用上有什么区别?
-
索引匹配要求:
- group by: 必须严格匹配索引的顺序(如 Group By cl,c2)需索引(c1, c2),否则可能触发松散索引扫描或临时表。
- group by:可部分匹配或非连续列排序(如 order by c1, c2)可用索引(c1, 长
c2, c3),但混合升降序或非索引列时需要额外排序。
-
覆盖索引优化
- group by: 覆盖索引可避免回表,直接完成分组
- order by: 覆盖索引可避免回表,但排序方向(ASC/DESC)需与索引一致。