【MySQL-索引调优】02:单列索引

1-问题

查询:

sql 复制代码
EXPLAIN SELECT * FROM orders WHERE user_id = 1234;

发现:

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE orders ALL 99520 10 Using where

分析:

  • select_type = SIMPLE:说明这是一个简单查询,没有子查询或UNION

  • table = orders :查询的表就是orders

  • partitions = NULL:没有分区

  • type = ALL这是最关键的,表示执行计划是 全表扫描。也就是说它没有用索引,而是把整张表都扫一遍

  • possible_keys = NULL:没有可用的索引

  • key = NULL关键,实际使用的索引也是空的,说明没有用索引

  • key_len = NULL:索引长度为空

  • ref = NULL:没有引用索引

  • rows = 99520关键,预估需要扫描大约 99,520 行数据

  • filtered = 10:表示大约只有 10% 的数据符合条件

  • Extra = Using where :说明是靠WHERE user_id = 1234这个条件来过滤

查询在orders表上做了全表扫描 ,效率比较低。如果orders表很大,性能会很差。原因是user_id字段没有索引,所以数据库只能把整张表读一遍再过滤

2-优化

  • 执行计划显示 type = ALL,也就是全表扫描
  • possible_keys = NULL,说明数据库认为没有合适的索引可以用
  • 查询条件是WHERE user_id = 1234`

可以新增user_id索引,提高查询速度

sql 复制代码
# 新增索引
CREATE INDEX idx_user_id ON orders(user_id);
# 再次运行
EXPLAIN SELECT * FROM orders WHERE user_id = 1234;

结果为:

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE orders ref idx_user_id idx_user_id 9 const 8 100

分析:

  • type = ref :这表示查询使用了非唯一索引(普通索引),通过索引来定位行,而不是全表扫描。相比之前的ALL,性能提升很大

  • possible_keys = idx_user_id :数据库识别到可以用idx_user_id这个索引

  • key = idx_user_id :实际使用的索引就是你刚建的idx_user_id

  • key_len = 9 :索引字段的长度(这里是user_id的存储长度)

  • ref = const :说明查询条件是一个常量(user_id = 1234),直接用这个值去索引里查

  • rows = 8:数据库预估只需要扫描大约8行,而不是之前的99,520行

  • filtered = 100:表示这些行几乎全部符合条件

相关推荐
努力成为AK大王1 天前
并发编程的核心挑战、优化方案与核心知识点总结
java·开发语言·数据库
En^_^Joy1 天前
Django开发:模板系统入门指南
数据库·django·sqlite
无关86881 天前
Redis Bitmaps 用户签到系统设计方案
数据库·redis·缓存
江华森1 天前
FastAPI 极速开发指南 — 从零到生产级 API 实战
数据库·fastapi
小小工匠1 天前
Redis - 如何使用 Redis 实现分布式锁
redis·性能优化·集群·并发
左直拳1 天前
mysql分区表自动归档
mysql·分区表·分区表归档
老纪1 天前
Redis分布式锁进第九零篇
数据库·redis·分布式
haven-8521 天前
MySQL事务ACID、隔离级别、MVCC、幻读解决
数据库·mysql
小高学习java1 天前
事务的边界问题,如何判断数据回滚时机。
java·数据库·后端