千家信息网

怎么合理的使用MySQL索引结构和查询

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要讲解了"怎么合理的使用MySQL索引结构和查询",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么合理的使用MySQL索引结构和查询"吧!一
千家信息网最后更新 2025年11月07日怎么合理的使用MySQL索引结构和查询

这篇文章主要讲解了"怎么合理的使用MySQL索引结构和查询",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么合理的使用MySQL索引结构和查询"吧!

一、高性能索引

1、查询性能问题

在MySQL使用的过程中,所谓的性能问题,在大部分的场景下都是指查询的性能,导致查询缓慢的根本原因是数据量的不断变大,解决查询性能的最常见手段是:针对查询的业务场景,设计合理的索引结构。

2、索引使用原则

索引的使用并不是越多越好,而是针对业务下的查询场景,不断的改进和优化,例如电商系统中用户订单的场景,假设存在如下表结构:

CREATE TABLE `ds_user` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',  `user_name` varchar(20) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';CREATE TABLE `ds_order` (  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',  `user_id` int(11) NOT NULL COMMENT '用户ID',  `order_no` varchar(60) NOT NULL COMMENT '订单号',  `product_name` varchar(50) DEFAULT NULL COMMENT '产品名称',  `number` int(11) DEFAULT '1' COMMENT '个数',  `unit_price` decimal(10,2) DEFAULT '0.00' COMMENT '单价',  `total_price` decimal(10,2) DEFAULT '0.00' COMMENT '总价',  `order_state` int(2) DEFAULT '1' COMMENT '1待支付,2已支付,3已发货,4已签收',  `order_remark` varchar(50) DEFAULT NULL COMMENT '订单备注',  `create_time` datetime DEFAULT NULL COMMENT '创建时间',  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表';

用户和订单的管理表,在电商的业务中很常见,可以通过对该业务分析,看看常用的索引结构:

用户方:

  • 基于用户的查询,多数是基于用户ID(user_id);

  • 基于订单号(order_no),查看物流的信息;

运营方:

  • 基于时间段的流水明细(create_time)或排序;

  • 基于订单状态的筛选(order_state)和统计;

  • 基于产品(product_name)的数据统计分析;

这样一个流程分析走下来,即可以在开发初期,确定哪些结构是查询必须用到的,预先做好索引结构,避免数据量庞大到影响性能时再去考虑使用索引。

有些时候会考虑放弃一些查询条件,例如基于产品名称的数据统计,走定时任务的方式,用来缓解表的查询压力,处理的方式是多样的。

优秀的索引设计,都是建立在对业务数据的理解上,考虑业务数据的查询方式,提高查询效率。

二、索引创建

1、单列索引

单列索引,即索引建立在表的一个字段上,一个表可以有多个单列索引,使用起来相对比较简单:

CREATE INDEX user_id_index ON ds_order(user_id) USING BTREE;

主键索引,或者上述的user_id_index都是单列索引。

业务场景:基于用户自己对订单查询,和管理系统,订单和用户的关联查询,所以订单表的user_id需要一个索引。

2、组合索引

组合索引包含两个或两个以上的列,组合索引相比单列索引复杂很多,如何建立组合索引,和业务关联度非常高,在使用组合索引时,还需要考虑查询条件的顺序。

CREATE INDEX state_create_time_index ON `ds_order`(`create_time`,`order_state`);

如上就是组合索引,实际包含的是2个索引 (create_time) (create_time,order_state),这样查询就涉及到最左前缀的原则,必须按照顺序来查询,这里下面详说。

业务场景:首先单说这里组合索引,在业务开发中,常见订单状态的统计,基于统计结果做运营分析,另外就是在运营系统中,基于创建时间段的筛选条件是默认存在的,避免全部数据实时扫描;一些其他的常见查询也都是条件加时间段的查询模式。

3、前缀索引

如果需要加索引的列是很长的字符串,那么索引会变的庞大臃肿,起到的效果可能并不是很明显。这时候可以截取列的前面一部分,创建索引,节省空间,这样可能会出现索引的选择性下降,即基于前缀索引查询出的相似数据可能很多:

ALTER TABLE ds_order ADD KEY (order_no(30)) ;

这里由于订单号太长,所以选择前面30位作为前缀索引,用作订单号的查询,当然这里涉及到一个非常经典的业务场景,订单号机制。

业务场景:前缀索引一个典型的应用场景就是处理订单号,一个看似很长的订单号,其实包含的信息非常多:

  • 时间点:就是订单生成的时间,年月日时分秒;

  • 标识位:即一个唯一的UID,保证订全单号唯一;

  • 埋点一:在很多业务中,在订单号记录产品类目;

  • 埋点二:通常会标识产品属性,例如颜色,口味等;

  • 错位符:防止订单号被分析,会随机一段错位符号;

如此一段分析下来,实际订单号是非常长的,所以需要引入前缀索引机制,前缀索引期望使用的索引长度可以筛选整个列的基数,例如上面的订单号:

  • 大部分业务基于时间节点筛选足够,即索引长度14位;

  • 如果是并发业务,很多时间节点相同,则索引长度是时间点+标识位;

注意:如果业务允许的情况下,一般要求前缀索引的长度有唯一性,例如上面的时间和标示位。

4、其他索引

例如全文索引等,这些用到的场景不多,如果数据庞大,又需要检索等,通常会选择强大的搜索中间件来处理。显式唯一索引,这种也会在程序上做规避,避免不友好的异常被抛出。

三、索引查询

如何创建最优的索引,是一件不容易的事情,同样在查询的时候,是否使用索引也是一件难度极大的事情,经验之谈:多数是性能问题暴露的时候,才会回头审视查询的SQL语句,针对性能问题,做相应的查询优化。

1、单列查询

这里直接查询主键索引,MySQL的主键一般选择自增,所以速度非常快。

EXPLAIN SELECT * FROM ds_order WHERE id=2;EXPLAIN SELECT * FROM ds_order WHERE id=1+1;EXPLAIN SELECT * FROM ds_order WHERE id+1=1;

这里,id=2,id=1+1,MySQL都可以自动解析,但是id+1是在索引列上执行运算,直接导致主键索引失效。这里有一个基本策略,如果非要在单列索引上做操作,可以将该逻辑放在程序中,到MySQL层面,SQL语句越干净利落越好。

2、前缀索引查询

前缀索引的查询,可以基于Like对特定长度筛选,或者全订单号查询。

EXPLAIN SELECT * FROM ds_order WHERE order_no LIKE '202008011314158723628732871625%';EXPLAIN SELECT * FROM ds_order WHERE order_no='20200801131415872362873287162572367';

3、组合索引查询

查询最麻烦的就是组合索引,或者说查询条件组合起来,都使用了索引:

EXPLAIN SELECT * FROM ds_order WHERE create_time>'2020-08-01 00:00:00' AND order_state='1';

上述基于组合索引中列的顺序,使用了组合索引:state_create_time_index。

EXPLAIN SELECT * FROM ds_order WHERE create_time>'2020-08-01 00:00:00';

上述只使用create_time列,也同样使用了索引结构。

EXPLAIN SELECT * FROM ds_order WHERE order_state='1';

上述如果只使用order_state条件,则结果显示全表扫描。

EXPLAIN SELECT * FROM ds_order WHERE create_time>'2020-08-01 00:00:00' AND order_no LIKE '20200801%';

上述则基于组合索引的create_time列和单列索引order_no保证查询条件都使用了索引。

通过上面几个查询案例,索引组合索引使用的注意事项如下:

  • 组合索引必须按索引最左列开始查询;

  • 不能跳过组合字段查询,这样无法使用索引。

感谢各位的阅读,以上就是"怎么合理的使用MySQL索引结构和查询"的内容了,经过本文的学习后,相信大家对怎么合理的使用MySQL索引结构和查询这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

索引 查询 订单 业务 组合 订单号 结构 前缀 场景 时间 数据 用户 性能 条件 就是 分析 长度 问题 统计 产品 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络技术实验ppt 上海的网络技术 jdbc连接数据库url 软件开发歌曲 东方口岸安全数据库找回密码 宁波嵌入式软件开发亿连信 软件开发主要学习什么 北京服务器维修维保云主机 澳洲网络安全产业 软件开发好还是会计好呢 嘉兴营销软件开发定做价格 欺诈数据库命中怎么消除 电脑宽带DNS服务器未响应 博山在线考试软件开发咨询 锋云服务器开机记录 升级系统补丁助力网络安全 保险公司有投保人的数据库吗 网络安全技术基础陆国浩 小程序数据库添加图片与删除 潍坊电商软件开发公司有哪些 梅州市土地利用总体规划数据库 魔兽世界转服务器时间 搜索网络安全胃炎的手抄报 我的世界无法连接至服务器中国版 网络安全与新枫桥经验分析 找软件开发程序员 华为服务器和威联通服务器比较 山东网络安全周活动 塔式服务器搭建 网络安全手抄报 易画A3的纸
0