加速你的数据库:公司中SQL优化的八大绝招

news2024/12/23 0:33:40

前言

        SQL优化这个问题也是老生常谈了,很多都还是在八股文中了解到,那么公司里的SQL都是咋优化的呢?和八股文一样吗?下面,我将与大家分享我在公司里学到的SQL优化知识。SQL优化是提高数据库性能和减少资源消耗的重要一环,在我工作的过程中,我深刻体会到了SQL优化的重要性,并积累了一些实用的技巧和经验,我希望通过这篇博客,将这些知识分享给大家。

LIKE的左模糊查询优化

不足点

使用 LIKE 进行左模糊查询可能导致索引失效的原因主要有两点:

  1. LIKE 模糊匹配规则:左模糊查询中,使用 % 通配符开头的模式,例如 %phone,在搜索过程中需要对索引进行全索引扫描,因为索引是按照顺序存储的,无法利用索引的 B-Tree 属性进行快速定位。这将导致查询时需要遍历整个索引,从而降低查询效率。
  2. 索引列顺序:如果索引列的顺序与查询条件的顺序不一致,也会导致索引失效。例如,如果索引是 (name, price),但是查询条件是 LIKE '%phone' AND price < 1000,这样的查询无法充分利用索引,因为索引的第一列 name 并没有在查询条件中使用,导致索引无法高效匹配查询条件。

优化点

        优先考虑使用全文搜索来进行模糊查询,可以大幅提高查询效率。因为全文搜索使用了特殊的索引类型(如InnoDB全文索引MyISAM全文索引),而左模糊查询则使用普通的B树索引。全文索引能够以文本内容的方式存储数据,并使用一定的算法构建索引,从而快速准确地找到文本数据中的匹配项,有效利用了索引。但左模糊查询需要扫描整个索引目录才能找到符合条件的记录,效率较低。因此,在适合的情况下,使用全文搜索可以提高查询效率。

优化实现

1. 添加全文索引:首先,需要为需要进行模糊查询的列添加全文索引。假设我们以 products 表中的 name 列为例,可以使用以下语句添加全文索引:

ALTER TABLE products ADD FULLTEXT(name);

2. 使用 MATCH AGAINST 进行全文搜索:接下来,使用 MATCH AGAINST 语句来进行全文搜索。使用 MATCH 子句指定要搜索的列,并使用 AGAINST 子句指定要搜索的模糊关键字。

SELECT * FROM products WHERE MATCH(name) AGAINST ('phone' IN NATURAL LANGUAGE MODE);

        在上述示例中,使用 MATCH(name) 来指定要搜索的列 name,并使用 AGAINST ('phone' IN NATURAL LANGUAGE MODE) 来指定要搜索的关键字,其中 phone 是模糊匹配的关键字。


NULL值处理优化

不足点

        对于 null 的判断可能会导致数据库引擎放弃使用索引而进行全表扫描。在数据库中,索引是用于加快数据检索的结构,它可以帮助数据库引擎快速定位需要的数据行。然而,当对一个列进行 null 值的判断时,由于 null 不属于实际的数据值,数据库引擎无法使用索引来加速查找,只能对整个表进行扫描来判断是否满足条件,此外,除了性能问题,对于业务而言,当遇到为NULL的数据,需要给他一个默认值,而非返回一个空数据,但是如果直接在表结构中声明该字段的默认值,那么就难以满足不同业务点所需不同默认值的情况。

优化点

  1. 可以通过 COALESCE 函数,COALESCE 函数可以用于检查多个列的空值,然后返回第一个非空的值(有点EXIST关键字的感觉)。这可以减少对每个列进行单独的 NULL 检查,简化查询语句的逻辑
  2. 使用 IFNULL 函数,它的作用似于Map集合的 getOrDefault 函数,用于判断一个表达式是否为NULL,当达式为NULL时返回一个指定的替代值。
  3. 使用索引,如果你经常需要检查一个列是否为 NULL,可以考虑为该列添加一个索引。索引可以帮助数据库更高效地定位包含 NULL 值的行,从而提高查询性能。

优化实现

使用 IS NULL 进行判空的 SQL 示例:

SELECT * FROM table WHERE column IS NULL;

上述示例中的 table 是表名,column 是要判断是否为空的列名。它将返回表中列值为空的所有行。

使用 COALESCE 进行优化的 SQL 示例:

SELECT COALESCE(column1, column2, column3) AS result FROM table; # COALESCE 函数将按照参数的顺序检查 column1、column2、column3 是否为空,并返回第一个非空的值作为结果。

使用 IFNULL 进行优化的 SQL 示例:

SELECT IFNULL(column, '替换的数据,注意数据类型') AS column_value FROM table; # IFNULL 函数将检查 column1 是否为 NULL,如果是,则将其替换为指定数据。

大表查询优化

不足点

        当一张表的数据非常多的时候,比如单个.myd文件都达到10G,这时,必然读取起来效率降低。深分页问题,数据检索慢等问题都比较频繁,哪怕加上索引都难以满足预期需求,

优化点

        对于这种情况可以考虑将数据按某字段数值进行分区切割,常见的有两种方案,通过数据库中间件MyCat进行分库分表,或者通过数据库自带的 PARTITION 函数进行数据分片。PARTITION 函数更加适合在单一数据库上进行数据的分区管理,而 MyCat 则适合将数据分布到多个物理服务器上进行横向扩展和提高性能。选择哪种分表方式应根据实际的需求、架构和使用场景来确定。

优化实现

(这里主要介绍PARTITION分区函数的优化,MyCat中间件的优化操作请参考我的MyCat 2全套学习笔记)

  1. 添加分区键:在表创建之后,通过 ALTER TABLE 语句添加分区键。
ALTER TABLE mytable ADD PARTITION BY RANGE(id)(
   PARTITION p0 VALUES LESS THAN (100),
   PARTITION p1 VALUES LESS THAN (200),
   PARTITION p2 VALUES LESS THAN (MAXVALUE)
);

        当执行插入操作后,mysql将会根据指定的规则,把数据放在不同的表文件上,相当于在文件上,被拆成了小块

image.png

2. 查询数据:使用查询语句可以按照分区键的规则查询分区表的数据。

SELECT * FROM mytable;               -- 查询所有分区的数据
SELECT * FROM mytable PARTITION(p0);  -- 查询指定分区(p0)的数据
SELECT * FROM mytable WHERE id < 200; -- 查询符合条件的分区数据

3. 修改分区规则:如果需要修改分区规则,可以使用 ALTER TABLE 语句进行更改。

ALTER TABLE mytable REORGANIZE PARTITION p2 INTO (PARTITION p2 VALUES LESS THAN (300));

4. 删除分区:如果需要删除分区,可以使用 ALTER TABLE 语句进行删除。

ALTER TABLE mytable DROP PARTITION p2;

避免列上函数和运算

不足点

        在 WHERE 子句中,如果索引列是计算或者函数的一部分,DBMS 的优化器将不会使用索引而使用全表扫描。同样的,不能在索引列上使用函数,因为函数也是一种计算,会造成全表扫描。索引失效的原因是索引是针对原值建的二叉树,将列值计算后,原来的二叉树就用不上了,从而导致全表扫描;

优化点

        其实本质而言是针对列值计算后,原二叉树失效问题,那么我们优化方案就要避免改动列值,以下主要方式有:1.通过模糊查询等价转换函数效果 2. 运算操作移到查询条件内

优化实现

-- 错误示例:函数应用于列上
SELECT * FROM users WHERE YEAR(name) = 2022;
​
-- 优化示例:将函数应用于查询条件的常量值
SELECT * FROM users WHERE name LIKE '2022%';
-- 错误示例:在列上进行运算
SELECT * FROM users WHERE age + 10 = 30;
​
-- 优化示例:将运算操作移到查询条件内
SELECT * FROM users WHERE age = 30 - 10;

 


大数据量操作EXISTS替代IN / WHERE

不足点

        数据量较大时,使用 IN 或 WHERE 子句可能导致查询性能下降。这是因为 IN 或 WHERE 子句需要分别检查每个值是否存在于目标数据集中,这会导致大量的比较操作和索引查找,增加查询的时间复杂度。并且会将目标数据集一次性加载到内存中进行比较,这可能导致内存不足或者大量的内存交换操作,从而影响整个系统的性能。

优化点

        在某些情况下,使用 EXISTS 可以更高效地执行查询,特别是当子查询的结果集很大时。这是因为 EXISTS 子查询只需找到符合条件的第一个匹配行即可停止,而 IN 或 WHERE 子查询需要扫描整个结果集并进行比较。并且EXISTS 只需要判断是否存在满足条件的行,不需要保存整个结果集

实际上,据库查询优化器有时候可能会在执行计划中进行自动转换。例如,当存在合适的索引时,优化器可能会将 IN 或 WHERE 子查询转换为 EXISTS 形式,以提高查询性能。

优化实现

使用 IN 子查询的查询示例:

SELECT column1, column2, column3
FROM table1
WHERE column1 IN (SELECT column1 FROM table2);

使用 EXISTS 替代的优化示例:

SELECT column1, column2, column3
FROM table1 AS t1
WHERE EXISTS (SELECT 1 FROM table2 AS t2 WHERE t2.column1 = t1.column1);
  • 对于表格 table1 的每一行,都执行 EXISTS 子查询的判断。
  • EXISTS 子查询会在 table2 中查找是否存在满足条件的记录。如果存在,返回结果为真,当前行被包含在查询结果中。
  • 如果不存在,返回结果为假,当前行不会被包含在查询结果中

深分页优化

不足点

        MySQL深分页问题是指在查询大量数据时,使用OFFSET和LIMIT来实现分页,当偏移量较大时(例如偏移量超过百万级别),查询的性能会明显下降,导致查询时间变长。OFFSET和LIMIT实际上是在获取查询结果之后再进行偏移和截取,这意味着数据库需要扫描和跳过大量的数据。并且MySQL需要将查询到的结果排序,然后丢弃前面的偏移量部分,这对于大量数据来说,可能需要进行大量的硬盘IO操作,降低了性能。

优化点

        其实根据以上说法,可以知道深分页产生原因在于MySQL在查询结果中跳过大量行时需要花费大量时间。例如,如果我们想获取第10000页的数据,MySQL需要先读取并跳过前9999页的数据,这将消耗大量时间。那么我们可以从两个方面进行入手,拿到上次查询的位置直接加1获取目标位置,或者使用覆盖索引 + 子查询优化查询。在进行分页查询时,我们可以记录上次查询的最后一个ID,然后在下次查询时,直接从这个ID开始查询,避免检索起始位置之前的数据。而覆盖索引是一种可以直接从索引中获取查询结果,而无需访问数据表的索引。通过使用覆盖索引,我们可以减少数据表的访问次数,从而提高查询效率。

优化实现

优化方式一:其实深分页问题的业务很多都与分页栏相关,那么我们就能够基于当前页码数据优化目标查询页码

SELECT * FROM table WHERE id > last_id ORDER BY id LIMIT 10;

优化方式二:既然速度慢在查询到目标行需要略过很多数据,那可以通过索引来进行优化速率,我快点越过其他的id,结果获取就快一点

SELECT * FROM mysql.test WHERE id > (SELECT a.id FROM mysql.test a WHERE a.create_time > '2014-01-01 00:00:00' LIMIT 100000, 1) LIMIT 10; 

优化方式三:对于经常被访问的页面或者数据,可以将其缓存在本地或者Redis等缓存中,在第二次及以后访问时直接返回缓存结果,避免重复计算和数据库查询。

优化方式四:对于经常被访问的页面或者数据,可以将其缓存在本地或者Redis等缓存中,在第二次及以后访问时直接返回缓存结果,避免重复计算和数据库查询。


使用UNION ALL代替UNION

不足点

        UNION 会自动去重,这意味着如果不需要去掉重复的行,使用 UNION会进行额外去重操作,从而降低查询性能。此外,当使用 UNION 时,数据库需要将所有的结果集合并并去重,这种操作可能会破坏每个结果集的排序,从而导致最终的结果集排序错误

优化点

        UNION ALL 不会去重,这意味着如果不需要去掉重复的行,使用 UNION ALL 可以避免进行额外的排序和去重操作,总之,如果需要去重,或者结果集已经是有序的,则应使用 UNION;否则,如果结果集不需要去重并且具有良好的排序,则应使用 UNION ALL。

优化实现

# UNION 
SELECT column1, column2, column3
FROM table1
UNION
SELECT column1, column2, column3
FROM table2;
​
# UNION ALL
SELECT column1, column2, column3
FROM table1
UNION ALL
SELECT column1, column2, column3
FROM table2;

批量处理避免频繁交互

不足点

        当需要更新的数据量特别大、SQL语句运行时间超长时。每次执行 SQL 都会涉及磁盘 I/O 操作,包括读取数据、日志写入等,特别是针对大量数据的操作,频繁的磁盘交互会导致性能的降低。并且每条 SQL 都会有网络传输的开销,包括发送 SQL 请求和接收响应,对于大量数据的处理,会产生较大的网络延迟。而且逐条执行 SQL 可能会导致频繁的加锁和解锁操作,增加了系统资源竞争的概率,可能导致锁冲突和阻塞,影响并发性能

优化点

        在做系统优化的时候,我们总是想尽可能的减少数据库查询的次数,以减少资源占用,同时可以提高系统速度。将多个 SQL 操作合并为一个批量操作,减少了磁盘交互次数和网络通信开销。通过一次性加载和处理多个数据,减少了多次查询的次数,提高了效率,并且结合批量操作,将一系列 SQL 操作放在一个事务中执行,保证数据的一致性和完整性,同时批量提交事务可以减少事务提交的次数,减小锁竞争的范围。

优化实现

# 批量插入
INSERT INTO table_name (column1, column2, column3)
VALUES
    (value1, value2, value3),
    (value4, value5, value6),
    ...
    (value7, value8, value9);
# 批量更新
Update users Set status=1 Where account IN ('xx1', 'xx2');
​
update users
 set job = case id
  when 1 then 'job11'
  when 2 then 'job12'
 end,
  age = case id
  when 1 then 11
  when 2 then 12
 end;

总结

        通过本篇博客,我们对SQL优化进行了深入的探讨和学习。我们首先了解了SQL优化的重要性和意义,它可以提高数据库的性能和减少资源消耗,从而提升系统的效率和响应速度。但是我们也要注意,SQL优化是一个复杂而细致的工作,需要结合具体的业务需求和数据库结构进行分析和优化。每个业务场景都可能存在不同的瓶颈和问题,因此,我们需要不断学习和实践,不断优化数据库性能,以满足不断增长的业务需求。

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

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

相关文章

金融行业案例分享 | 升级业务保障,HyperBDR助力巴西海通银行容灾上华为云

巴西海通银行通过HyperBDR成功将业务从本地VMware容灾上华为云&#xff0c;实现分钟级RTO&#xff0c;保障业务连续性同时优化容灾TCO。 项目背景 海通银行由海通证券股份有限公司控股&#xff0c;是一家受欧盟监管的银行&#xff0c;在葡萄牙里斯本注册成立&#xff0c;业务遍…

mysql定时备份shell脚本和还原

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言数据库备份分类mysqldump命令备份计划1.每日备份&#xff0c;保留30天备份文件2.每月1号备份&#xff0c;保留12个月备份文件 定时调度还原总结 前言 数据库备…

QT第1天

题目&#xff1a;点击按钮改变文字 需要增加一个count属性&#xff0c;并且只需要定义槽&#xff0c;信号函数已经内置好了 //widget.h#ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Wi…

数据分析讲课笔记01:数据分析概述

文章目录 零、学习目标一、本次课程概述二、数据分析的背景&#xff08;一&#xff09;进入大数据时代&#xff08;二&#xff09;数据分析的作用 三、什么是数据分析&#xff08;一&#xff09;数据分析的概念&#xff08;二&#xff09;数据分析的分类1、描述性数据分析2、探…

抛弃安卓,追赶iOS,鸿蒙能否成为中国第二大系统?

据半导体行业观察机构Techinsights发布报告预测&#xff0c;从2024年起&#xff0c;鸿蒙Harmony OS将取代苹果iOS&#xff0c;成为中国市场上第二大智能手机操作系统。 鸿蒙系统&#xff0c;支棱起来了&#xff01;去年&#xff0c;华为前脚“复活”麒麟芯片&#xff0c;后脚宣…

天津大数据分析培训班 常见的大数据培训课程

大数据现在属于热门职业技能之一&#xff0c;不管是大学毕业生&#xff0c;计算机和数据相关专业青年&#xff0c;已经工作一阵的开发人员&#xff0c;运营小白&#xff0c;还是其他想进入这个行当的&#xff0c;可能还没有编程基础的转行人&#xff0c;都想尝试大数据行业&…

2024年人工智能有哪些证书可以报考呢?

由国家工信部权威认证的人工智能证书是跨入人工智能行业的敲门砖&#xff0c;随着人工智能技术的发展越来越成熟&#xff0c;相关的从业人员也会剧增&#xff0c;证书的考取难度也会变高。如果已经从事或者准备从事人工智能行业的人员&#xff0c;对于考证宜早不宜迟&#xff0…

C语言之扫雷小游戏的实现【含递归展开】

文章目录 前言一、扫雷游戏代码设计思路二、设计扫雷代码1.创建菜单函数2.实现9x9扫雷3.初始化棋盘4.打印棋盘5.随机布置雷的位置6.排查雷的信息7.递归展开 三、源码1.新建一个test.c源文件2.新建一个game.c源文件3.创建一个game.h头文件 前言 扫雷游戏是1992年发行的一款大众类…

银河麒麟v10安装前端环境(Node、vue、Electron+vite)

此帖子所提到的所有依赖包都是基于银河麒麟v10真机的arm架构包&#xff0c;如果是在windows上的虚拟机上 把依赖包换成x64的包即可&#xff0c;方法步骤都是一样 一.node安装 原始方法安装&#xff08;建议用第二种nvm方法&#xff0c;因为更简单&#xff09;&#xff1a; 1…

Salesforce生态系统2024年就业趋势

对于Salesforce专业人士来说&#xff0c;新一年的开始都是激动人心的。但2023年仍存在显著挑战&#xff0c;经济技术低迷导致裁员&#xff0c;以及Salesforce生态系统增长放缓等等&#xff0c;这些挑战将延续到2024年。 回顾2023年 2023年&#xff0c;Salesforce生态系统以及…

Navicat 技术干货 | 为 MySQL 表选择合适的存储引擎

MySQL 是最受欢迎的关系型数据库管理系统之一&#xff0c;提供了不同的存储引擎&#xff0c;每种存储引擎都旨在满足特定的需求和用例。在优化数据库和确保数据完整性方面&#xff0c;选择合适的存储引擎是至关重要的。今天&#xff0c;我们将探讨为 MySQL 表选择合适的存储引擎…

反向传播(Back Propagation)

目录 回归简单模型的梯度计算 反向传播计算图链式求导链式法则定理&#xff1a; Forward 前馈计算反向传播Back Propagation例子线性模型的计算图计算前馈过程反向传播过程&#xff08;逆向求导&#xff09; 练习 Pytorch中的前馈过程和反向传播过程Tensor 回归 简单模型的梯度…

C#基础:通过QQ邮件发送验证码到指定邮箱

一、控制台程序 using System; using System.Net; using System.Net.Mail;public class EmailSender {public void SendEmail(string toAddress, string subject, string body){// 设置发件人邮箱地址以及授权码string fromAddress "xxxxxqq.com";string password …

LORA的基本原理

本文将介绍如下内容&#xff1a; 什么是Lora高效微调的基本原理LORA的实现方式LORA为何有效&#xff1f; 一、什么是LoRA LoRA 通常是指低秩分解&#xff08;Low-Rank Decomposition&#xff09;算法&#xff0c;是一种低资源微调大模型方法&#xff0c;论文如下: LoRA: Low…

【漏洞复现】优卡特脸爱云一脸通智慧管理平台文件上传漏洞

Nx01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大&#xff0c;运行稳定&#xff0c;操作简单方便&#xff0c;用户界面美观&#xff0c;轻松统计数据的一脸通系统。无需安装&#xff0c;只需在后台配置即可在浏览器登录。 功能包括&#xff1a;系统管理中心、人员信息管…

智慧校园实验室安全综合管理平台如何保障实验室安全?

一、建设思路 实验室安全综合管理平台是基于以实验室安全&#xff0c;用现代化管理思想与人工智能、大数据、互联网技术、物联网技术、云计算技术、人体感应技术、语音技术、生物识别技术、手机APP、自动化仪器分析技术有机结合&#xff0c;通过建立以实验室为中心的管理体系&…

局域网的好哥们——广域网

广域网&#xff08;Wide Area Network&#xff0c;WAN&#xff09;是一种覆盖范围广泛的网络&#xff0c;它连接了不同地理位置的计算机和网络设备&#xff0c;并允许它们进行数据通信和资源共享。本文将介绍广域网的基本概念&#xff0c;包括定义、特点、构成要素以及应用场景…

思维导图制作MindNode 2023中文

MindNode 2023是一款思维导图应用程序&#xff0c;专为创意和组织思维而设计。它通过直观的界面和强大的功能&#xff0c;帮助用户创建、编辑和分享思维导图。MindNode 2023支持多种主题和节点&#xff0c;允许用户自定义图标、颜色和形状&#xff0c;使思维导图更加清晰、有条…

策略模式-实践

俗话说&#xff1a;条条大路通罗马。在很多情况下&#xff0c;实现某个目标的途径不止一条&#xff0c;例如我们在外出 旅游时可以选择多种不同的出行方式&#xff0c;如骑自行车、坐汽车、坐火车或者坐飞机&#xff0c;可根据实 际情况&#xff08;目的地、旅游预算、旅游时间…

Linux第26步_在虚拟机中安装stm32wrapper4dbg工具

在Ubuntu下编译TF-A 或者 Uboot时&#xff0c;我们需要用到ST公司提供的stm32wrapper4dbg工具。stm32wrapper4dbg工具的源码下载地址为: GitHub - STMicroelectronics/stm32wrapper4dbg 记得我们在前面已经创建过的目录如下&#xff1a; 1&#xff09;、在根目录下&#xf…