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执行过程中,用户的任务…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
32位寻址与64位寻址
32位寻址与64位寻址 32位寻址是什么? 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元(地址),其核心含义与能力如下: 1. 核心定义 地址位宽:CPU或内存控制器用32位…...
