温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在MySQL中查询回表

发布时间:2021-09-16 15:59:20 来源:亿速云 阅读:227 作者:chen 栏目:云计算
# 怎么在MySQL中查询回表 ## 一、什么是回表查询 回表(Back to Table)是MySQL中InnoDB引擎特有的一种查询现象,指当SQL语句需要获取的列不在二级索引(非聚簇索引)中时,引擎需要根据索引中的主键值回到聚簇索引(主键索引)中重新查找完整数据行的过程。 ### 核心概念解析 1. **聚簇索引**:叶子节点存储完整数据行(如InnoDB的主键索引) 2. **二级索引**:叶子节点只存储主键值(如普通INDEX索引) 3. **回表代价**:需要额外的磁盘I/O操作 ## 二、回表查询的典型场景 ### 1. 非覆盖索引查询 ```sql -- 假设name是二级索引,age不在索引中 SELECT * FROM users WHERE name = '张三'; 

2. 索引条件下推失效

-- 即使有name索引,仍需回表查age SELECT * FROM users WHERE name = '张三' AND age > 20; 

3. 使用非索引列排序

-- 使用非索引列排序会导致回表 SELECT id FROM users ORDER BY create_time DESC; 

三、如何识别回表操作

1. 通过EXPLN分析

EXPLN SELECT * FROM users WHERE name = '张三'; 

观察Extra列: - Using index:未发生回表(覆盖索引) - NULLUsing where:可能发生回表

2. 性能监控工具

  • 使用SHOW PROFILE查看执行耗时
  • 监控handler_read_next状态变量

四、优化回表查询的8种方法

1. 使用覆盖索引

-- 创建包含所有查询字段的联合索引 ALTER TABLE users ADD INDEX idx_name_age(name, age); -- 查询改为只使用索引列 SELECT name, age FROM users WHERE name = '张三'; 

2. 索引条件下推(ICP)

-- MySQL 5.6+默认启用ICP SET optimizer_switch='index_condition_pushdown=on'; 

3. 使用主键查询

-- 直接使用聚簇索引避免回表 SELECT * FROM users WHERE id = 1001; 

4. 延迟关联

-- 先通过索引获取ID,再关联查询 SELECT t.* FROM users t JOIN (SELECT id FROM users WHERE name = '张三' LIMIT 100) tmp ON t.id = tmp.id; 

5. 合理设计索引

-- 将高频查询字段加入索引 ALTER TABLE orders ADD INDEX idx_customer_status(customer_id, status); 

6. 使用物化视图

-- 创建包含计算列的视图 CREATE VIEW user_stats AS SELECT id, name, COUNT(*) OVER() AS total_count FROM users; 

7. 分区表优化

-- 按范围分区减少扫描数据量 CREATE TABLE logs ( id INT, log_date DATE ) PARTITION BY RANGE (YEAR(log_date)) ( PARTITION p2020 VALUES LESS THAN (2021), PARTITION p2021 VALUES LESS THAN (2022) ); 

8. 使用内存临时表

-- 对中间结果使用内存临时表 SET tmp_table_size = 256M; SET max_heap_table_size = 256M; 

五、实战案例分析

案例1:电商订单查询优化

-- 原始低效查询(需回表) SELECT * FROM orders WHERE user_id = 1001 AND status = 2; -- 优化方案: -- 1. 创建联合索引 ALTER TABLE orders ADD INDEX idx_user_status(user_id, status); -- 2. 改写查询 SELECT order_id, total_amount FROM orders WHERE user_id = 1001 AND status = 2; 

案例2:分页查询优化

-- 低效分页(大量回表) SELECT * FROM products ORDER BY sales DESC LIMIT 10000, 20; -- 优化方案: SELECT t.* FROM products t JOIN (SELECT id FROM products ORDER BY sales DESC LIMIT 10000, 20) tmp ON t.id = tmp.id; 

六、监控与测量回表开销

1. 使用Performance Schema

-- 开启性能监控 UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE '%handler%'; 

2. 关键指标解读

  • handler_read_key:索引读取次数
  • handler_read_next:索引范围扫描次数
  • handler_read_rnd_next:全表扫描次数

七、总结建议

  1. 核心业务查询必须使用覆盖索引
  2. 单表索引数量建议不超过5个
  3. 长文本字段避免建立索引
  4. 定期使用ANALYZE TABLE更新统计信息
  5. 监控INNODB_BUFFER_POOL_READ_AHEAD预读情况

最佳实践:通过pt-index-usage工具分析索引使用情况,定期优化表结构。 “`

(注:实际字数约1250字,此处为精简展示版,完整版可扩展每个优化方法的实现细节和更多案例)

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI