mysql的trace追踪SQL工具,进行sql优化
trace是MySQL5.6版本后提供的SQL跟踪工具,通过使用trace可以让我们明白optimizer(优化器)如何选择执行计划。
注意:开启trace工具会影响mysql性能,所以只适合临时分析sql使用,用完之后请立即关闭。
测试数据脚本:
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`std_name` varchar(30) NOT NULL,`age` tinyint(3) unsigned NOT NULL,`class_id` int(11) unsigned NOT NULL,`gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `idx_std_age` (`age`),KEY `idx_std_name_age_class` (`std_name`,`age`,`class_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=100766 DEFAULT CHARSET=utf8mb4;--添加测试数据的存储过程DROP PROCEDURE IF EXISTS proc_insert_student;
DELIMITER $$
CREATE PROCEDURE proc_insert_student()
BEGINDECLARE i INT; SET i=1; WHILE i<=100000 DO INSERT INTO t_student(std_name,age,class_id) VALUES(CONCAT('Li Lei',i), (i MOD 120)+1 ,(i MOD 3)+1); SET i=i+1; END WHILE;
END $$-- 执行存储过程
call proc_insert_student();
trace工具用法
一.查看trace开关状态,默认关闭的
show variables like 'optimizer_trace';
二.开启face
1.会话级别临时开启,只在当前会话生效。
set session optimizer_trace="enabled=on",end_markers_in_json=on;
2.永久开启(重启失效)
注意用完关闭
set optimizer_trace="enabled=on";
三.用法
1.在查询sql后加上固定sql,例:
set session optimizer_trace="enabled=on",end_markers_in_json=on;
select * from t_student where std_name > 'a' order by age;
SELECT * FROM information_schema.OPTIMIZER_TRACE;
2.查看执行计划,并未使用到联合索引,联合索引name使用的范围查询,一般都不会用到索引。 如果用name索引需要遍历name字段联合索引树,然后还需要根据遍历出来的主键值去主键索引树里再去查出最终数据,成本比全表扫描还高 。
EXPLAIN SELECT * FROM t_student WHERE std_name > 'a' ORDER BY age;
EXPLAIN SELECT std_name,age,class_id FROM t_student WHERE std_name > 'a' ORDER BY age;
3。如果查询是联合索引字段,那就使用了覆盖索引,这样的name范围查询,联合索引才会使用到,这样只需要遍历name字段的联合索引树就能拿到所有结果,叶子节点只存放二级索引的数据,这就不用回表操作。
TRACE列的json数据拷贝出来查看。主要是看cost值,成本
SELECT * FROM information_schema.OPTIMIZER_TRACE;
{"steps": [{"join_preparation": { -- 第一阶段:SQL准备阶段,格式化sql"select#": 1,"steps": [{"expanded_query": "/* select#1 */ select `t_student`.`id` AS `id`,`t_student`.`std_name` AS `std_name`,`t_student`.`age` AS `age`,`t_student`.`class_id` AS `class_id`,`t_student`.`gmt_create` AS `gmt_create` from `t_student` where (`t_student`.`std_name` > 'a') order by `t_student`.`age`"}] /* steps */} /* join_preparation */},{"join_optimization": { -- 第二阶段:SQL优化阶段"select#": 1,"steps": [{"condition_processing": { -- 条件处理"condition": "WHERE","original_condition": "(`t_student`.`std_name` > 'a')","steps": [{"transformation": "equality_propagation","resulting_condition": "(`t_student`.`std_name` > 'a')"},{"transformation": "constant_propagation","resulting_condition": "(`t_student`.`std_name` > 'a')"},{"transformation": "trivial_condition_removal","resulting_condition": "(`t_student`.`std_name` > 'a')"}] /* steps */} /* condition_processing */},{"substitute_generated_columns": {} /* substitute_generated_columns */},{"table_dependencies": [ -- 表依赖详情{"table": "`t_student`","row_may_be_null": false,"map_bit": 0,"depends_on_map_bits": [] /* depends_on_map_bits */}] /* table_dependencies */},{"ref_optimizer_key_uses": [] /* ref_optimizer_key_uses */},{"rows_estimation": [ -- 预估表的访问成本{"table": "`t_student`","range_analysis": {"table_scan": { -- 全表扫描"rows": 100300, -- 行数"cost": 20351 -- 查询消耗} /* table_scan */,"potential_range_indexes": [ -- 查询可能使用的索引{"index": "PRIMARY", -- 主键索引"usable": false, -- 未使用"cause": "not_applicable" -- 原因:不适合},{"index": "idx_std_age", -- age索引"usable": false, -- 未使用"cause": "not_applicable" -- 原因:不适合},{"index": "idx_std_name_age_class", -- stdname,age,class的组合索引"usable": true, -- 使用"key_parts": ["std_name","age","class_id","id"] /* key_parts */}] /* potential_range_indexes */,"setup_range_conditions": [] /* setup_range_conditions */,"group_index_range": { -- group 用到的索引"chosen": false, -- 未使用"cause": "not_group_by_or_distinct" -- 原因:未使用group by 或者 distinct} /* group_index_range */,"analyzing_range_alternatives": { -- 分析各个索引使用成本"range_scan_alternatives": [{"index": "idx_std_name_age_class","ranges": ["a < std_name" -- 索引使用范围] /* ranges */,"index_dives_for_eq_ranges": true,"rowid_ordered": false, -- 使用该索引获取的记录是否按照主键排序"using_mrr": false,"index_only": false, -- 是否使用覆盖索引"rows": 50150, -- 索引扫描行数"cost": 60181, -- 索引使用成本"chosen": false, -- 是否选择该索引:否"cause": "cost" -- 原因:消耗}] /* range_scan_alternatives */,"analyzing_roworder_intersect": { -- 分析使用索引合并的成本"usable": false,"cause": "too_few_roworder_scans"} /* analyzing_roworder_intersect */} /* analyzing_range_alternatives */} /* range_analysis */}] /* rows_estimation */},{"considered_execution_plans": [ -- 分析出的执行计划{"plan_prefix": [] /* plan_prefix */,"table": "`t_student`","best_access_path": { -- 最优访问路径"considered_access_paths": [ --分析出的最终访问路径{"rows_to_scan": 100300,"access_type": "scan", -- 访问类型:为scan,全表扫描"resulting_rows": 100300,"cost": 20349,"chosen": true, -- 确定选择"use_tmp_table": true}] /* considered_access_paths */} /* best_access_path */,"condition_filtering_pct": 100,"rows_for_plan": 100300,"cost_for_plan": 20349,"sort_cost": 100300,"new_cost_for_plan": 120649,"chosen": true}] /* considered_execution_plans */},{"attaching_conditions_to_tables": { -- 为查询的表添加条件"original_condition": "(`t_student`.`std_name` > 'a')","attached_conditions_computation": [] /* attached_conditions_computation */,"attached_conditions_summary": [ -- 添加条件结果{"table": "`t_student`","attached": "(`t_student`.`std_name` > 'a')"}] /* attached_conditions_summary */} /* attaching_conditions_to_tables */},{"clause_processing": { -- order by 处理"clause": "ORDER BY","original_clause": "`t_student`.`age`","items": [{"item": "`t_student`.`age`"}] /* items */,"resulting_clause_is_simple": true,"resulting_clause": "`t_student`.`age`"} /* clause_processing */},{"reconsidering_access_paths_for_index_ordering": { -- 重构索引处理顺序"clause": "ORDER BY","steps": [] /* steps */,"index_order_summary": {"table": "`t_student`","index_provides_order": false,"order_direction": "undefined","index": "unknown","plan_changed": false} /* index_order_summary */} /* reconsidering_access_paths_for_index_ordering */},{"refine_plan": [{"table": "`t_student`"}] /* refine_plan */}] /* steps */} /* join_optimization */},{"join_execution": { -- 第三阶段:SQL执行阶段"select#": 1,"steps": [{"filesort_information": [{"direction": "asc","table": "`t_student`","field": "age"}] /* filesort_information */,"filesort_priority_queue_optimization": {"usable": false,"cause": "not applicable (no LIMIT)"} /* filesort_priority_queue_optimization */,"filesort_execution": [] /* filesort_execution */,"filesort_summary": {"rows": 100000,"examined_rows": 100000,"number_of_tmp_files": 14,"sort_buffer_size": 262016,"sort_mode": "<sort_key, packed_additional_fields>"} /* filesort_summary */}] /* steps */} /* join_execution */}] /* steps */
}
MySQL认为 全表扫描的成本低于索引扫描,所以mysql最终选择全表扫描,
4.关闭trace
set session optimizer_trace="enabled=off";
相关文章:

mysql的trace追踪SQL工具,进行sql优化
trace是MySQL5.6版本后提供的SQL跟踪工具,通过使用trace可以让我们明白optimizer(优化器)如何选择执行计划。 注意:开启trace工具会影响mysql性能,所以只适合临时分析sql使用,用完之后请立即关闭。 测试数…...

docker部署springboot jar包项目
docker部署springboot jar包项目 前提,服务器环境是docker环境,如果服务器没有安装docker,可以先安装docker环境。 各个环境安装docker: Ubuntu上安装Docker: ubuntu离线安装docker: CentOS7离线安装Docker࿱…...

一个八年工作经验老程序员的分享
作为一个 Java 程序员,我在这个行业中工作了多年。在这个过程中,我经历了许多挑战和机遇,也学到了很多宝贵的经验和教训。在这篇文章中,我想分享一些我的感想和思考,希望能够对其他 Java 程序员有所帮助。 一、技术的…...
代码随想录算法训练营第四十三天|动态规划|1049. 最后一块石头的重量 II、494. 目标和、474.一和零
1049. 最后一块石头的重量 II 文章 有一堆石头,每块石头的重量都是正整数。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x < y。那么粉碎的可能结果如下: 如果 x y&a…...
vue3+elementPlus:el-table-column表格列动态设置单元格颜色
:cell-style属性 //html<el-tableempty-text"暂无数据":data"datalist.table":max-height"height"row-key"id"border:cell-style"cellStyle"> <el-table>//js //动态设置单元格颜色 const cellStyle ({ row, c…...
python和shell脚本,每隔五分钟将远端服务器中的文件夹数据下载到跳板机
python脚本 import subprocess import datetime import timedef run_scp_command(source_path, target_path):command [scp -r , source_path, target_path]try:subprocess.run(command, checkTrue)print("File transferred successfully!")except subprocess.Call…...

Websocket在Asp.net webApi(.net framework)上的应用
之前在写看板部分的web api的时候,都是通过Ajax在规定时间内轮询调用web api,这样简单省事,但是当看板多了(并发量上来)以后,比较消耗服务器的性能,所以最近研究了websocket,希望使用…...

App前端开发跨平台框架比较:React Native、Flutter、Xamarin等
引言 移动应用开发领域的跨平台框架正在不断演进,为开发者提供更多选择。在本文中,我们将比较几个流行的跨平台框架:React Native、Flutter和Xamarin等。讨论它们的优缺点、适用场景以及开发体验。 第一部分 React Native: 优缺点、适用场景…...

VR数字展厅在企业中应用的优势有哪些?
随着VR全景技术的成熟,VR数字展厅逐渐成为了企业展示形象和产品的重要手段之一。VR企业数字展厅是一种通过VR技术、3D建模技术展示企业形象和产品的创新方式,将企业线下的展厅搬到线上,为企业品牌形象带来了很多优势。 VR数字展厅在企业中应用…...
【数据库】索引 视图 触发器 分页查询
目录 1、索引 2、视图 3、触发器 4、分页查询⚠️ 1、索引 提升查询效率、当数据量小的时候,索引看不出来效果,当数据量很大的时候,索引会显著提高查询速度 当给表添加索引之后,新插入一条数据,就会让索引进行重新…...

*地宫取宝c++
题目 输入样例1: 2 2 2 1 2 2 1输出样例1: 2输入样例2: 2 3 2 1 2 3 2 1 5输出样例2: 14 思路 题目说从入口开始,只能向右或向下行走到达右下角,类似“摘花生”这道题的模型。题目又说只有当格子里的宝…...
同态滤波算法详解
同态滤波是一种用于增强图像的方法,特别适用于去除图像中的照明不均和阴影。该算法基于照射反射模型,将图像分解为两个分量:照射分量(illumination component)和反射分量(reflection component)…...
财务管理系统报账和挂账分别什么区别!报销又是什么【第三期】
前言 已经写了两期 财务管理系统之saas多租户架构是什么以及分库分表以及如何选择分布式事务方案 【程序员聊业务】财务管理系统之模块分类 报账和挂账概念 报账是指企业或个人因业务需要而发生的各项费用支出,在支付后,需要将相关的票据、凭证等提交…...
最少刷题数
最少刷题数 题目分析 对于每一名同学计算还需要再刷多少题才能保证刷题数比他多的人数不超过刷题数比他少的学生人数。我们可以考虑统计每一个分数的前缀和数组,sum[i]表示当前学生中,刷题数小于等于i的人数。那么对于学生i的刷题数a[i],su…...

Python刘诗诗
写在前面 刘诗诗在电视剧《一念关山》中饰演了女主角任如意,这是一个极具魅力的女性角色,她既是一位有着高超武艺和智慧的女侠士,也曾经是安国朱衣卫前左使,身怀绝技且性格坚韧不屈。剧中,任如意因不满于朱衣卫的暴行…...
探索ChatGPT在软件架构师工作中的应用
随着人工智能技术的不断发展,自然语言处理模型如OpenAI的ChatGPT已经成为了解决各种实际问题的强大工具之一。在软件架构师这个领域,ChatGPT也有着广泛的应用。本文将探讨软件架构师如何有效地利用ChatGPT来解决问题和提高工作效率。 ChatGPT简介 Chat…...

pytest--allure报告中添加用例详情
前言 前面介绍了如何生成allure的报告,看着allure的页面非常好看,但是感觉少了一些内容,allure还可以增加一些用例详情内容,这样让我们的报告看着更加绚丽。 allure增加用例详情 我们可以在报告测试套件中增加用例详情内容。 …...

【深度学习笔记】9_5 多尺度目标检测
注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图 9.5 多尺度目标检测 在9.4节(锚框)中,我们在实验中以输入图像的每个像素为中心生成多个锚框。这些…...

Linux--vim
一.什么是vim Vim(Vi IMproved)是一种文本编辑器,通常在Linux和其他类Unix操作系统中使用。它是Vi编辑器的增强版本,提供了更多的功能和定制选项。Vim具有强大的文本编辑和编程功能,支持语法高亮、代码折叠、宏录制、…...

FreeRTOS操作系统学习——中断管理
中断管理介绍 嵌入式实时系统需要对整个系统环境产生的事件作出反应。这些事件对处理时间和响应时间都有不同的要求。事件通常采用中断方式检测,中断服务例程(ISR)中的处理量应当越短越好。ISR是在内核中被调用的, ISR执行过程中,用户的任务…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...

高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。
2024 年,高端封装市场规模为 80 亿美元,预计到 2030 年将超过 280 亿美元,2024-2030 年复合年增长率为 23%。 细分到各个终端市场,最大的高端性能封装市场是“电信和基础设施”,2024 年该市场创造了超过 67% 的收入。…...

如何做好一份技术文档?从规划到实践的完整指南
如何做好一份技术文档?从规划到实践的完整指南 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...

【工具教程】多个条形码识别用条码内容对图片重命名,批量PDF条形码识别后用条码内容批量改名,使用教程及注意事项
一、条形码识别改名使用教程 打开软件并选择处理模式:打开软件后,根据要处理的文件类型,选择 “图片识别模式” 或 “PDF 识别模式”。如果是处理包含条形码的 PDF 文件,就选择 “PDF 识别模式”;若是处理图片文件&…...