[MySQL面试题]-索引 41-44 使用 Order By 时能否通过索引排序?

96 阅读3分钟

image.png

41 使用 Order By 时能否通过索引排序

是,排序方向一致

  1. 索引列顺序匹配。
  2. 排序方向一致。
  3. 覆盖索引。

42 通过索引排序内部流程是什么?

select name,id from user where name like '%明' order by name;
  1. 查询优化器判断:若 order by 字段有可用索引且顺序匹配,优先使用索引排序

  2. 数据获取:

    1. 覆盖索引:直接通过索引获取所有字段,无需回表 。
    2. 非覆盖索引:取出排序字段和主键,可能触发回表。
  3. 排序执行:

    1. 单路排序:一次性加载所有字段到内存排序(需内存足够)
    2. 双路排序:分两次扫描磁盘。首次排序后回表取其他字段(内存不足时触发)
  4. 结果返回:排序后直接输出,减少随机I/O

  • 增大 sort_buffer_size 参数的设置
  • 增大 max_length_for_sort_date 参数的设置
  • 减少 select 后面的查询的字段,禁止使用 select *

43 什么是双路排序和单路排序?

  1. 单路排序(Single-Pass Sorting)

    1. 定义:一次性将所有需要排序的字段(包括查询字段和排序字段)加载到内存(sort_buffer)中进行排序,排序完成后直接返回结果。

    2. 特点:

      1. 内存充足时效率高。避免磁盘I/O
      2. 若字段总长度超过 max_length_for_sort_data 默认 1024 字节),则无法使用。
  2. 双路排序(Two-Pass Sorting)

    1. 定义:分两次扫描数据:

      1. 第一次:仅加载排序字段和主键到内存排序。
      2. 第二次:根据排序结果回表查询其他字段,合并后返回结果。
    2. 特点:

      1. 内存不足时触发,需写入临时文件并合并排序,增加I/O开销。
      2. 通过主键回表减少内存占用,但可能因多次I/O降低性能。

关键区别:

  • 数据加载:单路一次性加载所有字段,双路分两次加载。
  • 性能影响:单路依赖内存大小,双路依赖磁盘I/O。
  • 触发条件:由 max_length_for_sort_data 参数控制。

优化建议:

  • 增大 sort_buffer_size 和 max_length_for_sort_data 以减少双路排序。
  • 使用覆盖索引避免回表。

44 group by 分组和order by在索引使用上有什么区别?

  1. 索引匹配要求:

    1. group by: 必须严格匹配索引的顺序(如 Group By cl,c2)需索引(c1, c2),否则可能触发松散索引扫描或临时表。
    2. group by:可部分匹配或非连续列排序(如 order by c1, c2)可用索引(c1, 长

    c2, c3),但混合升降序或非索引列时需要额外排序。

  2. 覆盖索引优化

    1. group by: 覆盖索引可避免回表,直接完成分组
    2. order by: 覆盖索引可避免回表,但排序方向(ASC/DESC)需与索引一致。