mysql中使用前缀索引与性能优化技巧
发布时间 - 2026-01-11 00:00:00 点击率:次前缀索引长度应通过计算区分度确定:用COUNT(DISTINCT LEFT(col,N))/COUNT(*)≥0.95为基准,再结合EXPLAIN验证key_len和rows;必须显式指定长度,不支持ORDER BY/GROUP BY;复合索引中需注意字段顺序与区分度。
前缀索引到底该取多长?别猜,用 SELECT 算出来
前缀索引长度不是拍脑袋定的。太短,重复值多,索引失效;太长,浪费空间、拖慢写入。关键看字段值的**区分度**——即前 N 个字符能区分多少行数据。
实操步骤:
- 先估算区分度:用
COUNT(DISTINCT LEFT(column_name, N)) / COUNT(*),N 从 3 开始逐步试到 10 或 20 - 当结果 ≥ 0.95(即 95% 行能被唯一前缀覆盖),基本够用
- 对比不同 N 下的
EXPLAIN输出,确认key_len和rows是否明显下降
SELECT COUNT(*) AS total, COUNT(DISTINCT LEFT(email, 5)) AS prefix5, COUNT(DISTINCT LEFT(email, 8)) AS prefix8, COUNT(DISTINCT LEFT(email, 12)) AS prefix12 FROM users;
ALTER TABLE ... ADD INDEX 加前缀索引时,必须显式指定长度
MySQL 不允许对 TEXT/VARCHAR 类型字段直接建普通索引(除非你设了 innodb_large_prefix=ON 且行格式支持),但更常见的是加前缀索引。漏写长度会报错:ERROR 1071 (42000): Specified key was too long。
正确写法:
-
ALTER TABLE users ADD INDEX idx_email_prefix (email(12));—— 括号里是数字,不是函数 - 不能写成
email(LEFT(email,12))或email USING BTREE(后者语法错误) - 如果字段是
TEXT,必须加长度;VARCHAR(255)同样要写,否则默认用全列,可能超限制
前缀索引不支持 ORDER BY 和 GROUP BY 的完整排序/分组
这是最容易踩的坑:前缀索引只加速“查找”,不保存完整字段值,所以无法用于排序或去重逻辑。
比如:
-
SELECT * FROM users WHERE→ 走前缀索引 ✅
email LIKE 'abc%'; -
SELECT DISTINCT email FROM users;→ 无法用前缀索引去重 ❌(实际走全表扫描) -
SELECT * FROM users ORDER BY email LIMIT 10;→ 即使有email(12)索引,也大概率不走 ✅(除非WHERE条件已限定范围且优化器认为划算)
如果你依赖 ORDER BY email 性能,要么建完整长度索引(注意长度限制),要么在应用层缓存排序结果。
复合索引里混用前缀索引,顺序和长度都影响命中率
前缀索引可以作为复合索引的一部分,但它的“有效信息量”比完整索引低,容易让优化器放弃使用整个索引。
例如建了 (status, email(10), created_at):
- 查询
WHERE status = 'active' AND email LIKE 'test%'→ 可能走索引 ✅ - 但
WHERE email LIKE 'test%' AND created_at > '2025-01-01'→ 很可能不走,因为email不是索引最左列 ❌ - 如果
email(10)区分度差(比如大量邮箱以user_开头),优化器可能直接跳过这个复合索引
建议:把高区分度字段放前面;前缀字段尽量控制在区分度 ≥ 0.9;必要时用 FORCE INDEX 验证,但别在线上滥用。
前缀索引不是银弹——它省空间、快查询,但代价是丧失排序能力、增加评估成本。真正难的不是怎么建,而是判断“这里值不值得建”。每次加之前,先跑一遍 SELECT COUNT(DISTINCT ...),再看 EXPLAIN,比凭经验靠谱得多。
# mysql
# ai
# 邮箱
# count
# select
# Error
# using
# table
# 性能优化
# 不支持
# 不走
# 的是
# 这是
# 如果你
# 加前缀
# 一遍
# 值不值得
# 得多
# 线上
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
做企业网站制作流程,企业网站制作基本流程有哪些?
如何破解联通资金短缺导致的基站建设难题?
,网页ppt怎么弄成自己的ppt?
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
如何为不同团队 ID 动态生成多个非值班状态按钮
,在苏州找工作,上哪个网站比较好?
Swift中swift中的switch 语句
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
Python结构化数据采集_字段抽取解析【教程】
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
动图在线制作网站有哪些,滑动动图图集怎么做?
原生JS获取元素集合的子元素宽度实例
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
千库网官网入口推荐 千库网设计创意平台入口
C++时间戳转换成日期时间的步骤和示例代码
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全
网站建设保证美观性,需要考虑的几点问题!
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
Laravel如何使用Telescope进行调试?(安装和使用教程)
Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】
javascript中闭包概念与用法深入理解
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
Laravel如何使用withoutEvents方法临时禁用模型事件
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
LinuxShell函数封装方法_脚本复用设计思路【教程】
高端网站建设与定制开发一站式解决方案 中企动力
Python高阶函数应用_函数作为参数说明【指导】
Linux系统运维自动化项目教程_Ansible批量管理实战
如何在Ubuntu系统下快速搭建WordPress个人网站?
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
Android仿QQ列表左滑删除操作
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
利用JavaScript实现拖拽改变元素大小
如何在云服务器上快速搭建个人网站?
Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】
如何在阿里云香港服务器快速搭建网站?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
详解vue.js组件化开发实践
Android使用GridView实现日历的简单功能
如何在云主机上快速搭建网站?
济南网站建设制作公司,室内设计网站一般都有哪些功能?
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
制作旅游网站html,怎样注册旅游网站?
Laravel观察者模式如何使用_Laravel Model Observer配置


email LIKE 'abc%';