进阶功法:SQL 优化指南

目录标题

  • SQL 优化指南
    • 1. 插入数据优化
      • 1.1 批量插入数据
      • 1.2 手动提交事务
      • 1.3 主键顺序插入
      • 1.4 大批量插入数据
        • 步骤:
    • 2. 主键优化
      • 主键设计原则
      • 拓展知识
    • 3. ORDER BY 优化
      • 3.1 Using filesort
      • 3.2 Using index
        • 示例
      • 3.3 ORDER BY 优化原则
    • 4. GROUP BY 优化
        • 示例
      • 4.1 GROUP BY 优化原则
    • 5. LIMIT 优化
        • 示例
    • 6. COUNT 优化
      • 6.1 MyISAM
      • 6.2 InnoDB
      • 6.3 优化思路
      • 6.4 COUNT 的四种常见情况
      • 6.5 注意事项
    • 7. UPDATE 优化
        • 示例
      • 7.1 UPDATE 优化原则

SQL 优化指南

1. 插入数据优化

1.1 批量插入数据

在插入数据时,可以一次插入多条数据以进行 SQL 优化。通常建议一次插入 500 到 1000 条数据。

INSERT INTO tb_test VALUES (1, 'TOM'), (2, 'JERRY'), ...;

1.2 手动提交事务

SQL 在每条语句后都进行提交会影响整体性能。可以通过手动提交事务来减轻负担。

START TRANSACTION;INSERT INTO tb_test VALUES (1, 'TOM'), (2, 'JERRY');
INSERT INTO tb_test VALUES (3, 'TaM'), (4, 'JyRRY');
INSERT INTO tb_test VALUES (5, 'TeM'), (6, 'JiRRY');COMMIT;

1.3 主键顺序插入

主键的顺序插入会减轻 SQL 排序操作,直接插入加快速度。

示例:

  • 主键插入:1, 2, 3, 6, 9, 12, 40, 60…

1.4 大批量插入数据

如果一次性插入超大量数据,INSERT 语句的插入性能会很低。可以使用 LOAD DATA INFILE 方法插入数据。

步骤:
  1. 客户端连接服务端时,加上参数 --local-infile
    mysql --local-infile -u root -p
    
  2. 设置全局参数 local_infile 为 1,开启从本地加载文件导入数据的开关。
    SET GLOBAL local_infile = 1;
    
  3. 执行 LOAD DATA INFILE 指令将准备好的数据加载到表结构中。
    LOAD DATA LOCAL INFILE '/root/sql1.log' INTO TABLE tb_user FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
    

2. 主键优化

在 InnoDB 存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表。

主键设计原则

  1. 降低主键长度:满足业务需求的情况下,尽量降低主键的长度。
  2. 顺序插入:插入数据时,尽量选择顺序插入,使用 AUTO_INCREMENT 自增主键。
  3. 避免使用 UUID 或自然主键:如身份证号等。
  4. 避免修改主键:业务操作时,避免对主键的修改。

拓展知识

  • 页合并和页分裂

3. ORDER BY 优化

ORDER BY 排序具有两种排序方式:

3.1 Using filesort

通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区 sortbuffer 中完成排序操作。所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。

3.2 Using index

通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要额外排序,操作效率高。

示例
-- 使用 Using filesort
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY name;-- 使用 Using index
CREATE INDEX idx_user_age_phone_aa ON tb_user(age, phone);EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age, phone;
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age DESC, phone DESC;-- 创建混合排序索引
CREATE INDEX idx_user_age_phone_aa ON tb_user(age ASC, phone DESC);EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age ASC, phone DESC;

3.3 ORDER BY 优化原则

  1. 建立合适的索引:根据排序字段建立合适的索引,多字段排序时,遵循最左前缀法则。
  2. 覆盖索引:尽量使用覆盖索引。
  3. 多字段排序:一个升序一个降序时,注意联合索引在创建时的规则(ASC/DESC)。
  4. 增大排序缓冲区:如果不可避免地出现 FileSort,大数据量排序时,可以适当增大排序缓冲区大小 sort_buffer_size(默认 256k)。

4. GROUP BY 优化

GROUP BY 优化同样借助索引进行优化。

示例
-- 效率较低
EXPLAIN SELECT profession, COUNT(*) FROM tb_user GROUP BY profession;-- 建立索引后,效率提升
CREATE INDEX idx_user_pro_age_sta ON tb_user(profession, age, status);EXPLAIN SELECT profession, COUNT(*) FROM tb_user GROUP BY profession;

4.1 GROUP BY 优化原则

  1. 通过索引提高效率:在分组操作时,可以通过索引来提高效率。
  2. 最左前缀法则:分组操作时,索引的使用也是满足最左前缀法则的。

5. LIMIT 优化

LIMIT 用于分页操作,当数据量较大时,需要进行优化。

示例
# 当我们希望获得第900000个数据后的十个数据,就需要完全获得前9000000个数据才可以,这会损耗许多时间# 优化思路:
# 我们通过select只获得第9000000个后的十个数据的id
# 然后通过id对比来获得整行数据:EXPLAIN SELECT * FROM tb_sku t, (SELECT id FROM tb_sku ORDER BY id LIMIT 900000, 10) a WHERE t.id = a.id;

6. COUNT 优化

不同存储引擎处理 COUNT 的方式不同:

6.1 MyISAM

直接把表的总行数存储在磁盘中,运行 COUNT(*) 时直接输出。

6.2 InnoDB

需要一行一行读取数据,进行累加。

6.3 优化思路

在添加数据和删除数据时,同时存储其数据数量。

6.4 COUNT 的四种常见情况

COUNT 用法含义
COUNT(主键)InnoDB 引擎会遍历整张表,把每一行的主键值都取出来,返回给服务层。服务层按行进行累加(主键不可能为 null)。
COUNT(字段)没有 NOT NULL 约束:InnoDB 引擎会遍历整张表,把每一行的字段值都取出来,返回给服务层,服务层判断是否为 null,不为 null 计数累加。
NOT NULL 约束:InnoDB 引擎会遍历整张表,把每一行的字段值都取出来,返回给服务层,直接按行进行累加。
COUNT(1)InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加。
COUNT(*)InnoDB 引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。

6.5 注意事项

  • COUNT(1)COUNT(*) 速度基本相近,均为最快速度。
  • 按照效率排序:COUNT(字段) < COUNT(主键 id) < COUNT(1) ≈ COUNT(*),所以尽量使用 COUNT(*)

7. UPDATE 优化

InnoDB 的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁。

示例
-- 采用行锁
UPDATE course SET name = 'javaEE' WHERE id = 1;-- 采用表锁
UPDATE course SET name = 'SpringBoot' WHERE name = 'PHP';

7.1 UPDATE 优化原则

  1. 使用索引:更新操作尽量采用索引进行改变,这样锁就会变成行锁,只控制这一行数据。
  2. 避免表锁:如果更新操作没有使用索引,那么会采用表锁,导致整个表的数据都无法改变,影响其他人同步修改该表。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们处理,核实后本网站将在24小时内删除侵权内容。

在这里插入图片描述

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

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

相关文章

优雅的实现服务调用 -- OpenFeign

文章目录 1. RestTemplate存在问题2. OpenFeign介绍3. 快速上手引入依赖添加注解编写OpenFeign的客户端远程调用 4. OpenFeign参数传递从URL中获取参数传递单个参数传递多个参数传递对象传递JSON 5. 最佳实践Feign继承方式创建一个新的模块引入依赖编写接口打jar包服务实现方实…

javacpp调用pdfium的c++动态库

1、.h头文件 2、生成java代码的conf PdfiumDocumentConfigure.java package org.swdc.pdfium.conf;import org.bytedeco.javacpp.annotation.Platform; import org.bytedeco.javacpp.annotation.Properties; import org.bytedeco.javacpp.tools.InfoMap; import org.byte…

物联网:一种有能力重塑世界的技术

物联网&#xff08;IoT&#xff09;近年来对我们的日常生活产生了如此积极的影响&#xff0c;以至于即使是不懂技术的人也开始相信它所带来的便利以及敏锐的洞察力。 物联网是一场数字技术革命&#xff0c;其意义甚至比工业革命更为重大。物联网是仍处于起步阶段的第四次工业革…

SldWorks问题 2. 矩阵相关接口使用上的失误

问题 在计算三维点在图纸&#xff08;DrawingDoc&#xff09;中的位置时&#xff0c;就是算不对&#xff0c;明明就4、5行代码&#xff0c;怎么看都是很“哇塞”的&#xff0c;毫无问题的。 但结果就是不对。 那就调试一下吧&#xff0c;调试后发现生成的矩阵很不对劲&#…

电力设备图像分割系统源码&数据集分享

电力设备图像分割系统系统源码&#xff06;数据集分享 [yolov8-seg-efficientViT&#xff06;yolov8-seg-C2f-DCNV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI G…

分治算法(7)_归并排序_计算右侧小于当前元素的个数

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(7)_归并排序_计算右侧小于当前元素的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…

鸿蒙微内核IPC数据结构

鸿蒙内核IPC数据结构 内核为任务之间的通信提供了多种机制&#xff0c;包含队列、事件、互斥锁、信号量等&#xff0c;其中还有Futex(用户态快速锁)&#xff0c;rwLock(读写锁)&#xff0c;signal(信号)。 队列 队列又称为消息队列&#xff0c;是一种常用于任务间通信的数据…

ASP.NET MVC-懒加载-逐步加载数据库信息

环境&#xff1a; win10, .NET 6.0 目录 问题描述解决方案基础版数据库查询部分&#xff08;Entity Framework&#xff09;控制器前端页面 加载到表格版 问题描述 假设我数据库中有N个表&#xff0c;当我打开某页面时&#xff0c;每个表都先加载一部分&#xff08;比如20条&am…

Chainlit集成Dashscope实现语音交互网页对话AI应用

前言 本篇文章讲解和实战&#xff0c;如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型&#xff0c;阿里巴巴在github提供的有开…

有关vue路由的学习

导言 由于很久没碰前端了&#xff0c;碰到路由都不太会了。趁着后端对接来记录一下&#xff0c;就当复习。不过由于个人能力有限&#xff0c;这篇会偏向整个过程的实现逻辑&#xff0c;其中有很多具体的方法不会给来&#xff0c;有兴趣的可以去看一下源码~ 目的&#xff1a; …

基于springboot vue 校园失物招领平台的设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud等开发框架&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆…

SAP_SD模块-销售订单抬头折扣金额分摊到行项目的业务记录

前言&#xff1a; 本文主要是记录24年9月份支持财务月结过程中&#xff0c;用户提出的一个问题&#xff1a;“为什么KE30有部分物料9月份的销售数量少于FAGLL03H的销售数量&#xff1f;&#xff1f;”&#xff0c;主要包括以下两个内容&#xff1b; 1、问题发生的场景复现&am…

毕设分享 基于协同过滤的电影推荐系统

文章目录 0 简介1 设计概要2 课题背景和目的3 协同过滤算法原理3.1 基于用户的协同过滤推荐算法实现原理3.1.1 步骤13.1.2 步骤23.1.3 步骤33.1.4 步骤4 4 系统实现4.1 开发环境4.2 系统功能描述4.3 系统数据流程4.3.1 用户端数据流程4.3.2 管理员端数据流程 4.4 系统功能设计 …

【hot100-java】二叉树的最近公共祖先

二叉树篇 我觉得是比两个节点的深度&#xff0c;取min&#xff08;一种情况&#xff09; DFS解题。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ clas…

Apache Flink Dashboard

1、Overview Apache Flink Web Dashboardhttp://110.40.130.231:8081/#/overview 这张图片显示的是Apache Flink的Web UI界面&#xff0c;其中包含了以下几个部分&#xff1a; Available Task Slots: 显示当前可用的任务槽位数量。任务槽位是指Flink集群中可用于运行任务的资…

Django makemigrations时出现ModuleNotFoundError: No module named ‘MySQLdb‘

使用Python 3.11、Django 5.1.2 写完model进行makemigrations时出现报错 查找资料发现说是mysqldb适用于Python2&#xff0c;不支持Python3&#xff1b;python3可以使用pymysql 安装pymsql pip install pymysql 然后要在项目的__init__.py中加如下代码&#xff1a; import …

K8s(学习笔记)

swap分区是什么呀&#xff1f; 什么是ipvs呀&#xff1f; yaml是什么呀&#xff1f;&#xff1f;&#xff1f; p20看不下去了&#xff01;&#xff01;&#xff01;

【LeetCode】修炼之路-0004-Median of Two Sorted Arrays【python】

题目 Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). Example 1: Input: nums1 [1,3], nums2 [2] Output: 2.00000 Explanation: merged…

SPIE出版-EI会议-人机交互 虚拟现实 <<< 11月杭州

EI、Scopus检索|人机交互与虚拟现实国际会议征稿进行中❗会议已通过SPIE出版❗ 2024人机交互与虚拟现实国际会议 ✅大会时间&#xff1a;2024年11月15-17日 ✅大会地点&#xff1a;中国-杭州 ✅报名/截稿&#xff1a;2024年10月15日&#xff08;团队投稿可享优惠&#xff…

实现std::sort,replace,fill,accumulate,equal等函数

std::sort /// <summary>/// std::sort 是从小到大排列的/// </summary>/// <typeparam name"IteratorClass"></typeparam>/// <typeparam name"ComparingFunctions"></typeparam>/// <param name"itBegin&qu…