MySQL强制使用索引的两种方式及优化索引,使用MySQL存储过程创建测试数据。

news2024/11/27 3:53:58

一、MySQL强制使用索引的两种方式

1、使用 FORCE INDEX 语句:

explain
	select
		*
	from
		tbl_test force index (index_item_code)
	where
		(item_code between 1 and 1000) and (random between 50000 and 1000000)
	order by
		random
	limit 1;

使用 FORCE INDEX(索引名称)走索引:

2、使用 USE INDEX 语句:

explain
	select
		*
	from
		tbl_test USE index (index_item_code)
	where
		(item_code between 1 and 1000) and (random between 50000 and 1000000)
	order by
		random
	limit 1;

使用 USE INDEX(索引名称)走索引:

FORCE INDEX 或 USE INDEX 的区别?

  1. FORCE INDEX :这个语句指示MySQL强制查询使用特定的索引。它会忽略优化器的选择,无论索引的选择性如何,都会使用指定的索引。这意味着即使使用了不太适合的索引,MySQL也会强制使用它。这可能会导致性能下降,因为不适合的索引可能会导致查询变慢。
  2. USE INDEX :这个语句也允许你指定要使用的索引,但它与"FORCE INDEX"不同的是,它只是暗示MySQL在可能的情况下使用指定的索引。如果MySQL认为其他索引更适合查询,它仍然可以选择其他索引。这样可以保留一定的灵活性,让MySQL根据实际情况选择最佳的索引。

总的来说,"FORCE INDEX"是强制使用指定索引,而"USE INDEX"是暗示使用指定索引,但MySQL仍然可以根据优化器的判断选择其他索引。实际使用时,应根据具体情况进行评估选择。

二、具体实现数据如下

1、创建一张数据表及索引:

CREATE TABLE `tbl_test` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(100) NOT NULL COMMENT '姓名',
  `item_code` bigint NOT NULL COMMENT '子项编号',
  `order_code` varchar(100) NOT NULL COMMENT '订单编号',
  `id_card` varchar(30) NOT NULL COMMENT '身份证',
  `goods_number` bigint NOT NULL COMMENT '商品数量',
  `amount` decimal(6,2) NOT NULL COMMENT '金额',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `random` bigint NOT NULL COMMENT '数据数',
  PRIMARY KEY (`id`),
  KEY `index_item_code` (`item_code`),
  KEY `index_id_card` (`id_card`),
  KEY `index_random` (`random`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

注:表创建完成后,使用如下命令新增索引:

-- 查看tbl_test表中全部的索引信息
show index from tbl_test;

添加索引:

-- 在tbl_test表中,goods_number列上创建索引
CREATE INDEX index_goods_number ON tbl_test (goods_number);

删除索引:

-- 在tbl_test表中,删除名称为 index_goods_number 的索引
ALTER TABLE tbl_test DROP INDEX index_goods_number;

2、创建存储过程:

-- 创建存储过程
create procedure insert_data() begin declare i INT default 1;
while i <= 100000 DO
insert into test.tbl_test (
    name,
	item_code,
	order_code,
	id_card,
	goods_number,
	amount,
	create_time,
	random)
values (
   CONCAT("test", i),
   i,
   CONCAT("order", i),
   FLOOR(RAND() * 10000000000000),
   i,
   ROUND(RAND() * 100, 2),
   NOW(),
   FLOOR(RAND() * 1000000)
 );
set
i = i + 1;
end while;
end
-- 结束

执行完成后,可在此处查看:

然后,调用存储过程:

-- 调用储存过程
CALL insert_data();

执行完后,数据信息如下:

这里,可以通过存储过程的执行时间,看看慢SQL的定位方式

三、慢SQL的发现

1、执行show variables like '%general%'; 命令,查看日志功能是否开启

主要使用命令如下:

  1. set global general_log=on; 这个语句将全局变量 general_log 的值设置为 "on",表示启用了全局查询日志。启用后,MySQL服务器将记录所有的查询语句到查询日志文件中,包括 SELECT、INSERT、UPDATE、DELETE 等操作。
  2. set global general_log=off; 这个语句将全局变量 general_log 的值设置为 "off",表示禁用了全局查询日志。禁用后,MySQL服务器将停止记录查询日志,不再将查询语句写入查询日志文件。

通过修改全局变量 general_log 的值,可以控制全局查询日志的开启和关闭。

2、查看当前慢查询日志的开启情况

-- 查看当前慢查询日志的开启情况
show variables like '%quer%';

执行信息如下:

设置信息解析:

  1. binlog_rows_query_log_events:该属性设置为"OFF",表示不记录二进制日志中的查询事件。
  2. ft_query_expansion_limit:该属性设置为20,表示在全文搜索查询中,扩展查询的限制为最多20个词。
  3. have_query_cache:该属性设置为"NO",表示当前MySQL服务器未启用查询缓存功能。
  4. log_queries_not_using_indexes:该属性设置为"OFF",表示不记录未使用索引的查询语句。
  5. log_throttle_queries_not_using_indexes:该属性设置为0,表示未使用索引的查询语句不会被限制。
  6. long_query_time:该属性设置为10.000000,表示执行时间超过10秒的查询将被认为是慢查询。
  7. query_alloc_block_size:该属性设置为8192,表示分配给查询内存块的大小为8KB。
  8. query_prealloc_size:该属性设置为8192,表示预分配给查询的内存大小为8KB。
  9. slow_query_log:该属性设置为"ON",表示慢查询日志功能已启用。
  10. slow_query_log_file:该属性设置为"DESKTOP-0R9IERO-slow.log",表示慢查询日志文件的名称为"DESKTOP-0R9IERO-slow.log"。

我们通过解析,还是默认设置慢日志阀值为10秒 (设置命令:set global long_query_time = 10)

通过slow_query_log_file的值,我们找到慢SQL文件DESKTOP-0R9IERO-slow.log,我这里在本地C盘:C:\ProgramData\MySQL\MySQL Server 8.0\Data 目录下:

慢SQL日志信息,查看存储过程的执行情况:

四、索引的优化

1、EXPLAIN 是一个在 MySQL 中用于查询执行计划的命令。它可以帮助您了解查询语句的执行方式、优化和性能。

EXPLAIN SELECT * FROM table_name WHERE column = 'value';

以下是 EXPLAIN 命令的一些关键信息:

  1. id:表示查询的标识符,如果查询包含子查询,每个子查询都有一个唯一的标识符。
  2. select_type:表示查询的类型,常见的类型包括 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。
  3. table:表示查询涉及的表名。
  4. type:表示访问表的方式,常见的类型有 ALL(全表扫描)、INDEX(索引扫描)、RANGE(范围扫描)等。
  5. possible_keys:表示可能应用到查询中的索引。
  6. key:表示实际使用的索引。
  7. key_len:表示索引字段的长度。
  8. ref:表示与索引比较的列或常数。
  9. rows:表示估计需要扫描的行数。
  10. Extra:提供其他额外的信息,如是否使用了临时表、排序方式等。

通过分析 EXPLAIN 的输出,您可以获得以下信息:

  • 查询是否有效利用了索引。
  • 查询的执行顺序和方式。
  • 哪些表被访问以及访问方式。
  • 估计扫描的行数和数据访问的成本。

这些信息可以帮助您优化查询语句、调整索引和改进性能。

2、常见索引优化1:条件字段函数操作

当前表中已创建索引:

函数作用在条件列上,索引失效:

修改后:

2、常见索引优化2:隐式类型转换

当前id_card字段在数据库中是 varchar 类型,直接以数值类型查询,导致索引失效:

修改后,如下:

-- 使用如下写法:
explain select * from tbl_test where id_card != '2674841548013'
-- 或者:
-- CAST(267484154801 AS CHAR) 将数值类型的 2674841548013 转换为与 id_card 列的数据类型( varchar )匹配的字符类型。
-- 通过这样做,确保了 id_card 和值之间的比较使用匹配的数据类型,使索引能够有效使用。 
explain select * from tbl_test where id_card = CAST(2674841548013 AS CHAR)

失效的原因跟案例一类型,数据类型隐式转换,对于优化器来说,这个语句相当于:

select * from tbl_test where  CAST(id_card AS signed int) = 66778899;

这样,在WHERE 子句中使用函数、表达式或算术,索引列错误使用,导致索引失效。

3、常见索引优化3:隐式字符编码转换

当使用不同的字符集进行隐式编码转换时,可能会导致索引失效。这是因为MySQL在进行索引查找时,会使用字符集的排序规则进行比较。如果字符集不同,排序规则也会不同,从而导致索引无法正确使用。

例如下面的例子,因字符集utf8mb4和utf8隐式字符编码转换而导致索引失效的情况:

假设有一个表my_table,其中有一个名为column的列,该列使用utf8mb4字符集,并且创建了索引。

CREATE TABLE my_table (  
  id INT PRIMARY KEY,  
  column VARCHAR(255) CHARACTER SET utf8mb4  
) ENGINE=InnoDB;  
  
CREATE INDEX idx_column ON my_table (column);

然后,我们向表中插入一些数据:

INSERT INTO my_table (id, column) VALUES (1, 'abc');  
INSERT INTO my_table (id, column) VALUES (2, 'def');

现在,如果我们使用不同字符集的查询语句进行隐式编码转换,可能会导致索引失效。例如,以下查询使用了utf8字符集的字符串进行查询,这与表中的utf8mb4字符集不同:

SELECT * FROM my_table WHERE column = 'ghi';

在这个情况下,由于字符集不同,MySQL无法正确使用索引,从而进行全表扫描。这会导致查询性能下降,因为全表扫描比使用索引更耗时。要避免这种情况,可以确保查询语句中的字符集与表中的字符集一致,或者显式地进行字符编码转换。

五、MySQL索引失效原因的大致汇总

1、前导模糊查询不能利用索引,比如查询语句是LIKE '%XX'或LIKE '%XX%',而'A%'就可以正常使用索引。
2、如果MySQL估计使用全表扫描要比使用索引快,则不使用索引。
3、OR前后存在非索引的列,索引失效。如果想使用OR,又想让索引生效,只能将OR条件中的每个列都加上索引。
4、普通索引的不等于不会走索引,如果是主键,则还是会走索引;如果是主键或索引是整数类型,则还是会走索引。
5、is null可以使用索引,is not null无法使用索引。
6、在设计表时设置NOT NULL约束最好,比如将INT类型的默认值设为0,将字符串默认值设为''。
7、如果在查询条件中对索引列使用了任何操作(计算,函数),或者进行了类型转换,可能会导致索引失效。
8、如果在复合索引中,查询条件没有遵循最左匹配原则,那么索引可能也不会生效。
9、如果MySQL优化器认为全表扫描的速度快于使用索引,它可能会选择全表扫描而不使用索引。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1042476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「华为P60 Pro」只要599元,老牌国产再现骚操作

国内智能手机经过这么些年的洗牌&#xff0c;真正活下来且过得滋润其实也就那屈指可数的几家。 刚开始大家还能拼创意、拼设计&#xff0c;最后发现拼来拼去&#xff0c;还是逃不开同质化命运。 到了现在&#xff0c;也不比啥创意了&#xff0c;干脆堆配置、卷规格一条路走到…

14.TIM输出比较示例程序(PWM驱动LED呼吸灯PWM驱动舵机PWM驱动直流电机)

目录 输出比较相关库函数 PWM驱动LED呼吸灯 PWM驱动舵机 PWM驱动直流电机 输出比较相关库函数 1.OC初始化&#xff08;掌握&#xff09; // 配置输出比较模块&#xff0c;输出比较单元有四个&#xff0c;对应也有四个函数 // 第二个参数是结构体&#xff0c;就是输出比较…

Docker的相关知识介绍以及mac环境的安装

一、什么是Docker 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题&#xff1a; 依赖关系复杂&#xff0c;容易出现兼容性问题开发、测试、生产环境有差异 Docker就是来解决这些问题的。Docker是一个快速交付应用、运行应用的技术&#x…

互联网医院牌照|互联网医院牌照审批流程和材料

随着科技的不断进步和社会的发展&#xff0c;互联网医院已经成为了当前的热点。而互联网医院的准入门槛自然也就越来越高。如果您计划成立一个互联网医院&#xff0c;您需要了解申请互联网医院牌照所需要注意的方面以及申请的流程。 一、资质申请前的准备 1、立项阶段准备 在立…

Python异步框架大战:FastAPI、Sanic、Tornado VS Go 的 Gin

一、前言 异步编程在构建高性能 Web 应用中起着关键作用&#xff0c;而 FastAPI、Sanic、Tornado 都声称具有卓越的性能。本文将通过性能压测对这些框架与Go的Gin框架进行全面对比&#xff0c;揭示它们之间的差异。 原文&#xff1a;Python异步框架大战&#xff1a;FastAPI、Sa…

文心一言 VS 讯飞星火 VS chatgpt (101)-- 算法导论9.3 7题

七、用go语言&#xff0c;设计一个 O(n)时间的算法&#xff0c;对于一个给定的包含n个互异元素的集合 S 和一个正整数k≤n&#xff0c;该算法能够确定 S 中最接近中位数的k个元素。 文心一言&#xff1a; 要设计一个 O(n) 时间的算法来找到集合 S 中最接近中位数的 k 个元素&…

诊断27服务介绍

在UDS诊断协议中,有一些服务,比如2E服务写入DID数据,2F服务控制输入输出,它们都会改变ECU控制器的内存数据,所以在请求这类服务时需要慎之又慎。诊断协议设计了一个安全解锁机制,让ECU在接收到某些诊断服务(2E、2F等)前需要处于解锁状态,这就是27服务实现。 Tester发…

【校招VIP】前端操作系统之存储管理-交换

考点介绍&#xff1a; 前端开发的时候&#xff0c;在页面刷新之后&#xff0c;我们的所有数据都会被清空&#xff0c;这时候就要用到本地存储技术了&#xff0c;前端的存储数据的方式有四种&#xff1a;cookie、localStorage、sessionStorage和indexDB。 本期分享的前端操作系…

JavaScript简介引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 JavaScript简介&引入方式 简介&#xf…

手把手教你实现:将后端SpringBoot项目部署到华为云服务器上

前言 前提&#xff1a;有一个后端项目&#xff0c;项目能够运行在本地&#xff0c;可以通过本地访问&#xff08;localhost&#xff09; 如果没有可以看这篇&#xff1a;一个基于SpringBoot的后端项目 注册华为云账号 华为云官网 购买云服务器 产品 -> 华为云耀云服务器…

数据结构--插入排序

目录 插入排序 算法实现 算法效率分析 插入排序的优化-折半插入排序 最终的结果&#xff1a;&#xff08;方式&#xff09; 优化-折半查找的代码实现 ​回顾 插入排序 算法实现 算法效率分析 空间复杂度和问题规模无关 插入排序的优化-折半插入排序 之前的元素有序&am…

【2023集创赛】加速科技杯三等奖作品:私密性高精度刷手身份认证系统

本文为2023年第七届全国大学生集成电路创新创业大赛&#xff08;“集创赛”&#xff09;加速科技杯三等奖作品分享&#xff0c;参加极术社区的【有奖征集】分享你的2023集创赛作品&#xff0c;秀出作品风采&#xff0c;分享2023集创赛作品扩大影响力&#xff0c;更有丰富电子礼…

pdf怎么压缩?pdf压缩方法大全

pdf怎么压缩&#xff1f;PDF是一种广受欢迎的文件格式&#xff0c;相信现在有很多用户都在使用。这是因为PDF具有出色的兼容性&#xff0c;适用于包含数据、图片、表格和文字等各种内容&#xff0c;不管是在电脑、手机、平板上&#xff0c;都可以让文件以最规范的方式打开呈现给…

垃圾收集器ParNewCMS与底层三色标记算法

JVM字节码文件class&#xff1a;&#xff08;16进制&#xff09; 前四个字节码CA FE BA BE&#xff0c;固定logo包含lineNumberTable&#xff1a;用于异常的定位默认第一个localVariableTable为this&#xff0c;无构造方法也会存在最大接口数FFFF 》65535包含最大操作数栈深度…

【算法思想】贪心

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

postgresql,在pgAdmin中修改列名称和列的类型

修改列名 alter table "表名称" rename "旧列名" to "新名称";是否要加引号要看情况&#xff0c;不加引号如果报错&#xff0c;就要加上。无引号&#xff1a;那么所有内容将自动为小写&#xff0c;不区分大小写&#xff1b;带引号&#xff1a;所…

网络安全,weblogic漏洞复现

WebLogic是美国Oracle公司出品的一个Java应用服务器&#xff0c;是一个基于JAVAEE架构的中间件&#xff0c;用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用。 2|0弱口令登陆部署shell文件 App Weblogic Path weblogic/weak_password 2|1介绍 用户管理…

Error: @vitejs/plugin-vue requires vue (>=3.2.13) or @vue/compiler-sfc

启动项目 npm run dev报错&#xff1a; vue3项目运行报错&#xff0c;试了很多方法都无法解决时&#xff0c;请再查看一下是否node版本是否正确&#xff0c;nodejs版本不能低于 16

安防视频/集中云存储平台EasyCVR(V3.3)部分通道显示离线该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

MySQL系统架构设计

MySQL 一、MySQL整体架构1.1 SQL接口1.2 解析器 Parser1.3 查询优化器 Optimizer1.3.1 逻辑优化1.3.2 物理优化1.3.3 explain 1.4 缓存 Cache1.5 存储引擎 Stroage Management1.6 一条查询SQL的执行流程 二、缓存池&#xff08;Buffer Pool&#xff09;2.1 Buffer Pool 预读机制…