mysql的索引优化与数据库存储引擎选择

发布时间 - 2026-01-28 00:00:00    点击率:
WHERE条件未走索引主因是索引失效:隐式类型转换、索引列用函数、联合索引缺失最左前缀、IS NULL在部分版本不走索引;InnoDB聚簇索引需回表,MyISAM索引存物理地址;MEMORY仅适用于临时数据;联合索引顺序应按查询中WHERE和ORDER BY字段组合确定。

为什么 WHERE 条件用了字段却没走索引?

常见现象是执行 EXPLAIN SELECT * FROM t WHERE status = 'active'; 显示 type=ALL,即全表扫描。根本原因往往不是没建索引,而是索引失效:

  • status 字段类型为 VARCHAR,但查询时写了 WHERE status = 1(隐

    式类型转换)
  • 在索引列上用了函数,比如 WHERE UPPER(name) = 'JOHN'
  • 联合索引 (a,b,c),只用 WHERE b = ?WHERE a = ? AND c = ?(缺少最左前缀)
  • 索引列允许 NULL,且查询条件是 IS NULL,某些 MySQL 版本下无法使用索引(尤其 MyISAM

验证方式:用 SHOW INDEX FROM t; 看索引结构,再用 EXPLAIN FORMAT=TRADITIONAL 查看实际是否命中。

InnoDBMyISAM 在索引设计上的关键差异

二者 B+ 树组织方式不同,直接影响你建什么索引、怎么写查询:

  • InnoDB 主键即聚簇索引,数据行直接存于主键 B+ 树的叶子节点;二级索引叶子存的是主键值,回表成本真实存在
  • MyISAM 所有索引都是非聚簇的,叶子节点存的是行物理地址(.MYD 文件偏移),没有“回表”概念,但不支持事务和行锁
  • 如果你频繁按 user_id 查询并需要返回大量字段,InnoDB 下把 user_id 设为主键或建覆盖索引(如 INDEX idx_uid_name_age (user_id, name, age))能避免回表
  • MyISAMCOUNT(*) 很快(内部维护行数),但 InnoDB 必须扫索引树——所以不要在大表上无条件用 SELECT COUNT(*)

什么时候该用 MEMORY 引擎?别只看“快”

MEMORY 表数据全在内存,SELECT 极快,但极易误用:

  • 只适合临时中间结果、缓存维度表(如城市字典)、或秒级生命周期的会话数据
  • 不支持 TEXT/BLOB 类型,也不支持外键和事务
  • 服务器重启后数据全丢——如果误把用户订单表设为 MEMORY,就是生产事故
  • 默认用哈希索引(HASH),只支持等值查询(=);范围查询(BETWEEN>)必须显式声明 USING BTREE
CREATE TABLE tmp_user_cache (
  id BIGINT PRIMARY KEY,
  name VARCHAR(64),
  updated_at DATETIME
) ENGINE=MEMORY
  DEFAULT CHARSET=utf8mb4
  AVG_ROW_LENGTH=128;

联合索引字段顺序到底怎么排?看查询模式,不是看字段重要性

错误认知:“把区分度高的字段放前面”。真正决定顺序的是 WHEREORDER BY 的组合模式:

  • 如果常查 WHERE category = ? AND status = ? ORDER BY created_at DESC,索引应为 (category, status, created_at),而非反过来
  • 如果还有 WHERE category = ? ORDER BY status ASC,那 (category, status) 就比单列 category 更有效
  • 注意 ORDER BY 方向一致性:(a ASC, b DESC) 在 MySQL 8.0+ 才支持,旧版本会忽略 b 的排序,降级为文件排序(Using filesort
  • 索引总长度别超限制:InnoDB 单索引前缀最大 3072 字节(utf8mb4 下约 768 个字符),超了会截断,导致后缀字段失效

最常被忽略的一点:索引不是越多越好。每个写操作都要更新所有相关索引,高并发写入场景下,5 个索引可能比 1 个慢 3 倍以上——先看慢查询,再加索引,别预设。


# mysql  # go  # 字节  # ai  # 隐式类型转换  # 为什么  # NULL  # count  # select  # format  # using  # 类型转换  # 并发  # 数据库  # 的是  # 主键  # 设为  # 用了  # 如果你  # 也不  # 都要  # 什么时候  # 适用于  # 写了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  如何在腾讯云服务器快速搭建个人网站?  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Laravel如何处理CORS跨域请求?(配置示例)  网站制作软件免费下载安装,有哪些免费下载的软件网站?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  C++用Dijkstra(迪杰斯特拉)算法求最短路径  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  如何快速上传建站程序避免常见错误?  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  详解vue.js组件化开发实践  常州企业网站制作公司,全国继续教育网怎么登录?  Android自定义控件实现温度旋转按钮效果  如何在自有机房高效搭建专业网站?  如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环  中山网站推广排名,中山信息港登录入口?  详解MySQL数据库的安装与密码配置  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  LinuxCD持续部署教程_自动发布与回滚机制  如何用虚拟主机快速搭建网站?详细步骤解析  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  如何在企业微信快速生成手机电脑官网?  Laravel如何使用Gate和Policy进行授权?(权限控制)  如何快速生成橙子建站落地页链接?  微信小程序 HTTPS报错整理常见问题及解决方案  如何在七牛云存储上搭建网站并设置自定义域名?  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  如何在万网利用已有域名快速建站?  Laravel如何实现文件上传和存储?(本地与S3配置)  如何续费美橙建站之星域名及服务?  佛山企业网站制作公司有哪些,沟通100网上服务官网?  🚀拖拽式CMS建站能否实现高效与个性化并存?  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  如何快速打造个性化非模板自助建站?  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  JavaScript实现Fly Bird小游戏  如何选择可靠的免备案建站服务器?  Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  微信h5制作网站有哪些,免费微信H5页面制作工具?  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  米侠浏览器网页背景异常怎么办 米侠显示修复  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  北京的网站制作公司有哪些,哪个视频网站最好?  零基础网站服务器架设实战:轻量应用与域名解析配置指南