【Sql优化】数据库优化方法、Explain使用

文章目录

      • 一、金字塔优化模型
      • 二、SQL优化的利器:Explain工具
        • 1. Explain 的作用
        • 2. Explain 的用法
      • 三、SQL优化方法(后续文章细讲)
        • 1. 创建索引减少扫描量
        • 2. 调整索引减少计算量
        • 3. 索引覆盖
        • 4. 干预执行计划
        • 5. SQL改写
      • 四、通过 Explain 优化案例
        • 案例1:消除全表扫描
        • 案例2:优化连接查询
      • 五、总结

数据库优化是提高系统性能的关键环节,尤其在面对高并发、大数据量场景时显得尤为重要。优化方法通常呈现“金字塔”结构,从 SQL及索引优化库表结构优化系统配置优化硬件优化,成本逐步提高,而效果逐步减弱。本文将围绕这些优化方法,详细介绍如何通过 Explain 工具分析SQL执行计划,及其在优化中的具体应用。


一、金字塔优化模型

数据库优化方法可以分为以下四个层次:

  1. SQL及索引优化
    • 性价比最高,通过调整查询语句和索引设计即可显著提高性能。
  2. 库表结构优化
    • 通过修改表结构和字段设计,减少冗余或不合理的数据存储。
  3. 系统配置优化
    • 调整数据库缓存、连接池等参数,改善资源分配。
  4. 硬件优化
    • 升级服务器硬件,如扩展内存、增加磁盘I/O吞吐能力。

通常的优化顺序是从下到上,优先选择成本较低的方式。

在这里插入图片描述


二、SQL优化的利器:Explain工具

Explain 是 MySQL 中用于分析查询执行计划的重要工具,可以直观展示查询的执行顺序、索引使用情况等信息。通过 Explain,开发者可以快速定位查询瓶颈,并采取相应优化措施。

1. Explain 的作用
  • 确定表的读取顺序
    确认查询中表与表之间的读取优先级,识别可能存在的顺序问题。
  • 显示查询的访问类型
    分析是否存在全表扫描等低效操作(如 ALL),以便调整索引或优化条件。
  • 分析索引的使用情况
    确定查询可能使用和实际使用的索引,发现未使用索引的情况。
  • 估算扫描的记录行数
    判断查询的影响范围,避免不必要的大量数据扫描。
  • 提供查询额外信息
    例如是否使用了临时表、排序或文件排序等低效操作。
2. Explain 的用法

执行 Explain 查询语句:

EXPLAIN SELECT * FROM users WHERE name = 'John';

在 MySQL 5.7 及之后版本中,Explain 默认返回以下列信息:

列名含义
id查询的标识号,值越大优先级越高
select_type查询类型(如SIMPLEPRIMARYSUBQUERY 等)
table涉及的表名
type查询访问类型(如ALLINDEXRANGE 等,效率从低到高)
possible_keys查询可能使用的索引
key实际使用的索引
rows预估扫描的行数
filtered符合条件的数据百分比
extra查询的额外信息(如Using IndexUsing Filesort 等)

三、SQL优化方法(后续文章细讲)

1. 创建索引减少扫描量

在大表中执行查询时,如果没有索引,通常会进行全表扫描,导致性能低下。通过为查询字段添加索引,可以快速定位数据。例如:

CREATE INDEX idx_name ON users(name);
2. 调整索引减少计算量

优化索引设计,例如使用复合索引,将查询条件中的多个字段合并到一个索引中,可以减少查询计算量。

3. 索引覆盖

索引覆盖是指查询只需从索引中获取数据,而无需回表。例如:

SELECT name FROM users WHERE age > 30;

如果为 age 字段添加索引,并且查询的列仅包括索引字段,则避免了回表查询。

4. 干预执行计划

通过 Explain 提供的执行计划,调整SQL语句或使用提示(Hint)优化执行路径。例如:

SELECT * FROM users FORCE INDEX (idx_name) WHERE name = 'John';

举例说明

假设:

  • orders 表有 100 万条记录,并在 user_id 上有索引。
  • users 表有 10 万条记录,但 status 字段没有索引。

普通 JOIN 查询

EXPLAIN SELECT * FROM orders o JOIN users u ON o.user_id = u.user_id WHERE u.status = 'active';

执行计划可能如下:

idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEusersALLNULLNULL100000Using where
2SIMPLEordersrefuser_iduser_id5000
  • 优化器选择了 users 表作为驱动表。
  • 因为 status 没有索引,users 表需要全表扫描。

使用 STRAIGHT_JOIN

EXPLAIN SELECT * FROM orders o STRAIGHT_JOIN users u ON o.user_id = u.user_id WHERE u.status = 'active';

执行计划可能如下:

idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEordersrefuser_iduser_id5000
2SIMPLEusersALLNULLNULL500Using where
  • orders 表被优先扫描,通过 user_id 索引减少了扫描量。
  • 关联时,只需要对 users 表的部分记录进行过滤。
5. SQL改写

通过将复杂的SQL拆解为多个简单查询或优化查询条件来提高性能。例如,将嵌套查询改写为关联查询:

改写前

SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE status = 'completed');

改写后

SELECT u.* 
FROM users u
JOIN orders o ON u.id = o.user_id 
WHERE o.status = 'completed';

四、通过 Explain 优化案例

案例1:消除全表扫描

问题:查询执行计划显示 type=ALL,表示全表扫描。
优化:为查询字段创建索引。

-- 优化前
EXPLAIN SELECT * FROM users WHERE name = 'John';-- 优化后
CREATE INDEX idx_name ON users(name);
EXPLAIN SELECT * FROM users WHERE name = 'John';
案例2:优化连接查询

问题:多表关联查询扫描行数过多。
优化:通过复合索引减少关联表的扫描量。

-- 优化前
EXPLAIN 
SELECT u.name, o.order_date 
FROM users u 
JOIN orders o ON u.id = o.user_id;-- 优化后:为连接字段添加索引
CREATE INDEX idx_user_id ON orders(user_id);
EXPLAIN 
SELECT u.name, o.order_date 
FROM users u 
JOIN orders o ON u.id = o.user_id;

五、总结

数据库优化是一项系统性工作,应优先选择成本低、效果好的方式,如 SQL及索引优化Explain 工具作为SQL优化的利器,可以帮助我们分析查询的执行计划,发现性能瓶颈。结合创建索引、调整执行计划、SQL改写等手段,可以大幅提升查询性能。优化并非一次性的工作,而是需要持续监控和调整。


博客主页: 总是学不会.

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

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

相关文章

Deepmotion技术浅析(五):运动追踪

运动追踪是 DeepMotion 动作捕捉和 3D 重建流程中的核心模块之一。该模块的主要任务是在视频序列中跟踪人体的运动轨迹,捕捉人体各部分随时间的变化,并生成连续的 3D 运动数据。DeepMotion 的运动追踪技术结合了计算机视觉、深度学习和物理模拟等方法&am…

Android 系统应用重名install安装失败分析解决

Android 系统应用重名install安装失败分析解决 文章目录 Android 系统应用重名install安装失败分析解决一、前言1、Android Persistent apps 简单介绍 二、系统 persistent 应用直接安装需求分析解决1、系统应用安装报错返回的信息2、分析解决 三、其他1、persistent系统应用in…

使用Nexus3搭建npm私有仓库

一、npm介绍 npm的全称是Node Package Manager,它是一个开放源代码的命令行工具,用于安装、更新和管理Node.js模块。npm是Node.js的官方模块管理器,它允许用户从一个集中的仓库中下载和安装公共的Node.js模块,并将这些模块集成到…

【ChatGPT】解锁AI思维链:如何让机器像人类一样思考?

在人工智能领域,我们一直在追求让机器像人类一样思考。然而,即使是最先进的AI,也常常被诟病缺乏“常识”,难以理解复杂问题,更不用说像人类一样进行逻辑推理和解决问题了。最经常的表现就是遇到不会的地方,…

蓝桥杯刷题——day5

蓝桥杯刷题——day5 题目一题干解题思路一代码解题思路二代码 题目二题干解题思路代码 题目一 题干 给定n个整数 a1,a2,⋯ ,an,求它们两两相乘再相加的和,即: 示例一: 输入: 4 1 3 6 9 输出: 117 题目链…

监测预警智能分析中心建设项目方案

随着科技的不断进步,地理信息与遥感技术在国家治理、环境保护、灾害预警等领域发挥着越来越重要的作用。监测预警智能分析中心的建设,旨在通过集成先进的遥感技术、地理信息系统(GIS)、大数据分析和人工智能(AI&#x…

【漫话机器学习系列】009.词袋模型(Bag of Words)

词袋模型(Bag of Words, 简称 BoW) 词袋模型是一种常见的文本表示方法,主要用于自然语言处理(NLP)和信息检索领域。它将文本数据转换为特征向量,忽略语序,仅考虑词的出现与否或出现频率。 1. 基…

vue3 setup语法,子组件点击一个元素打印了这个元素的下标id,怎么传递给父组件,让父组件去使用

问: vue3 setup语法,子组件点击一个元素打印了这个元素的下标id,怎么传递给父组件,让父组件去使用 回答: 在 Vue 3 中,你可以使用 setup 语法糖和组合式 API 来实现子组件向父组件传递数据。具体来说&am…

分治算法(单选题)

2-1 分数 2 下列多少种排序算法用了分治法? 堆排序插入排序归并排序快速排序选择排序希尔排序 A.2 B.3 C.4 D.5 正确答案 A 2-2 分数 2 分治法的设计思想是将一个难以直接解决的大问题分割成规模较小的子问题,分别解决问题,最后将子…

【栈】栈的定义及基本操作

1. 栈的定义和特点 定义:栈是限定尽在表尾进行插入或删除操作的线性表。 表头元素成为栈底,表尾元素成为栈顶。 特点:后进先出(先进后出) 2. 顺序栈 顺序栈是利用顺序存储结构实现的栈,即用一组连续…

UNIX简史

从1991年Linux出现至今,由于众多IT巨头以及技术社区的推动,Linux已经成为非常成熟、可用于各种关键领域的操作系统,适当了解其发展历史,对于理顺其技术流派、从而更好地学习和使用Linux具有重要意义。由于其基于UNIX系统二十多年的…

C# OpenCV机器视觉:畸变矫正

在一个阳光明媚的早晨,阿强决定去拍照。他拿起相机,穿上他最喜欢的羊毛大衣,准备记录下生活中的美好瞬间。可是,当他兴奋地查看照片时,发现自己拍的每一张都像是被外星人用变形金刚的力量扭曲过一样!“这是…

读书|关于马斯克

于我而言,马斯克是一个有魅力的人,他张扬嚣张、却又一直做着惊世骇俗的事情。 关于健康 马斯克本身的工作就十分忙碌,但早年的他生活习惯也极其不规律,睡眠不足、饮食糊弄、懒得运动。健康三要素一个不占。另外, 42 …

tryhackme——Defensive Security Intro(防御安全简介)

任务一:Introduction to Defensive Security防御安全简介 此room的两个要点: Preventing intrusions from occurring 防止入侵发生Detecting intrusions when they occur and responding properly 检测发生的入侵并正确响应 防御安全还有更多内容。 除上…

使用rust语言创建python模块(pyo3+maturin)

1. 首先使用conda创建python虚拟环境(已创建的可省略) >conda create --prefixE:\python_envs\rust_python python3.11 2. 激活python虚拟环境 conda activate rust_python 3. 安装maturin pip install maturin 4. 创建rust项目 >cd E:\py…

阿里云RAM实战详解

引言 阿里云RAM(Resource Access Management)是一款用于管理阿里云资源访问权限的服务。通过RAM,您可以为不同的用户分配不同的访问权限,确保资源的安全和可控。本文将详细介绍RAM的实战应用,结合最佳实践,帮助您更好地管理阿里云资源。 RAM的核心概念 在使用RAM之前,…

解锁CSS新维度:预处理器之LessSass

在现代前端开发中,CSS(层叠样式表)是用于控制网页外观的主要技术。然而,随着项目的复杂度增加,传统的CSS编写方式逐渐显现出其局限性,如变量复用、嵌套规则、模块化管理等需求难以满足。为此,出…

C++中函数的特性

文章目录 一、C中形参带默认值的函数二、C中的inline内联函数三、C中的inline内联函数和普通函数的区别四、C中函数重载五、C为什么支持函数重载六、C语言为什么无法实现函数重载 一、C中形参带默认值的函数 在C中,形参带默认值的函数是指在函数声明或定义时&#…

关于Postgresql旧版本安装

抛出问题 局点项目现场,要求对如下三类资产做安全加固,需要在公司侧搭建测试验证环境,故有此篇。 bclinux 8.2 tomcat-8.5.59 postgrel -11 随着PG迭代,老旧版本仅提供有限维护。如果想安装老版本可能就要费劲儿一些。现在&…

使用echarts实现3d柱状图+折线图

以下代码有问题请直接问国内直连GPT/Claude HTML 需要注意threeDchart一定要设置宽度高度&#xff0c;不然图不显示,然后echarts版本不要太低&#xff0c;不然也不显示 <div id"threeDchart" class"threeDchart"></div>js set3DBarChart2(dat…