SQL性能规范

news2024/11/24 4:19:22

一、随聊

记录一下吧,2023年7月13日00:11:11,现在的状态真的很,忙,干不完的活,希望巨大的压力,能够让自己快速成长,回想我这一路,21年大专毕业,用一年时间熟悉软件,快捷键,熟悉开发思维,数据库、JS、HTML、Java都只能算是皮毛,故而当年没有选择Java开发,目前从事数据分析,帆软报表,餐饮零售业务多一点,涵盖,财务、门店、产品、会员、供应链、加盟商等多种场景。越发觉得,成年世界的残酷,多少次想过放弃,想想自己身后空无一人,唯有自渡,便继续咬紧牙关砥砺前行。有感而发~最近加班有点严重,博客断更了很久了~

以下分享自己的工作笔记~~~

二、、SQL性能规范

简介:在项目中常用优化策略。针对本章的内容,需要掌握以下能力:

(1)了解数据库运算时基础的内存、硬盘交互,

(2)了解数据表扫描,基于对扫描的理解来提升SQL执行效率,

(3)了解执行计划,掌握到这一层级可以满足90%项目的需求。

基本理念:当我们执行SQL查询语句时,数据库的操作是先根据SQL语句从硬盘中获取数据,然后加载进内存中进行后续计算。由于SQL语句有执行的先后顺序,因此当SQL一开始查询的数据量越小,加载进内存时间越短,并且整个SQL执行也越快。

1、明确字段,不取多余

解释只取我们需要的字段,不用的不取。不要随意用“*”来查询全部。例如:

假设A表总共有10个字段,只需要用到其中两个字段,那么查询语句中只取我们需要的两个字段,速度比查询所有字段的速度快。

2、大表关联,先做过滤

解释大表关联查询语句中,做到先过滤再关联。不允许使用WHERE来进行关联。提前过滤好,在硬盘和内存交互上、内存计算上可以节省很多时间。

例如

 

3、提取共性,减少重复

解释SQL语句中有多处重复的子查询,可以将其提取出来,进行参数化,减少数据库查询次数。

例如,以下语句中重复使用了一个子查询:

SELECT employee_id, first_name, last_name,

       (SELECT department_name FROM departments WHERE department_id = employees.department_id) AS department_name,

       (SELECT AVG(salary) FROM employees WHERE department_id = 80) AS avg_salary

FROM employees

WHERE salary > (SELECT AVG(salary) FROM employees)

ORDER BY department_name;

可以将子查询提取出来进行参数化,如下所示:

CREATE VIEW department_names AS

SELECT department_id, department_name

FROM departments;

CREATE VIEW avg_salaries AS

SELECT department_id, AVG(salary) as avg_salary 

FROM employees

GROUP BY department_id;

SELECT employee_id, first_name, last_name, department_names.department_name, avg_salaries.avg_salary

FROM employees

JOIN department_names ON employees.department_id = department_names.department_id

JOIN avg_salaries ON employees.department_id = avg_salaries.department_id

WHERE salary > (SELECT AVG(salary) FROM employees)

ORDER BY department_name;

通过将子查询提取到视图中,并且使用JOIN语句将相关表连接起来,可以避免多次执行相同的子查询,从而提高查询效率。

4、减少不必要的扫描计算

解释:如果UNION ALL可满足要求,就使用UNION ALL,而不用UNION,因为UNION会有一个比较然后去重的过程,而UNION ALL没有。

5、经常查询的大数据量表,需要创建索引,过滤和排序尽量放在索引列上操作

解释:索引会提高SELECT效率,但是会影响到INSERT及UPDATE的效率。索引的介绍、什么时候应该加索引、什么时候不建议加索引等内容不在此赘述。

创建方式:

-- 新建索引

CREATE INDEX index_name ON table_name(column_name);

-- 新建组合索引

CREATE INDEX index_name ON table_name(column_name1, column_name2, ...);

-- 修改索引

ALTER TABLE table_name DROP INDEX index_name;

ALTER TABLE table_name ADD INDEX index_name (column_name1, column_name2, ...);

-- 删除索引

DROP INDEX index_name ON table_name;

-- 查询单表索引

SHOW INDEX FROM table_name;

6、避免显式转换、隐式转换导致索引失效

解释避免数据库运算时对索引列进行转换,例如:

(1)显示转换举例,假设索引列为日期型数据,和字符串型日期比较。

错误写法:TO_CHAR(T.索引列,'YYYYMMDD')>='20190715',

这里是用函数将索引列由日期类型转换为字符串类型,导致索引失效。

正确写法:T.索引列 >=TO_DATE('20190715',’YYYY-MM-DD’)

(2)隐式转换举例,假设索引列是一串字符串型的数字,取索引列值为1的数据。

错误写法:T.索引列=1

这里是数据库用隐式转换将索引由字符串类型转换成数值类型,导致索引失效。

正确写法:T.索引列=’1’

7、大表查询时,避免子查询中的排序计算,排序需放在执行计划最后一步

解释:尽量在子查询中避免ORDER BY、DISTINCT等语句。其中ORDER BY是对结果进行排序,而DISTINCT和GROUP BY是在计算过程中排序。子查询数据量较大时用EXISTS子句代替DISTINCT。

8、决策报表中,尽量将多个数据集合并为同一个数据集,减少并发数量

解释:一个数据集就是一个并发,数据集过多导致并发过高,数据库加载压力大,计算效率会降低。可以用以下方案减少决策报表中的数据集数量:

(1)将A、B、C三个指标的每月/每日的趋势,以年月/年月日为条件进行关联,而不是每个指标单独一个数据集。

(2)查询结果为一条记录的数据集,直接关联在一起,例如三个数据集A、B、C都返回一条记录,那么可以如下图进行数据集合并处理。

建议同比环比能一个数据集查询出来就用一个数据集查询

如下图

 

9、报表中控件的数据字典如果数据量过大,并且涉及到控件联动,此时将一个数据集拆开成多个数据集可以提高控件加载效率,与本条规则相违背,需要酌情考虑。

三、EXPLAIN 命令

EXPLAIN 命令来查看 MySQL 的查询执行计划

  1. id:每个 SELECT 子句或者操作表的唯一 ID。
  2. select_type:表示是哪种 SELECT 类型,例如 SIMPLE(简单 SELECT,不包含子查询或 UNION)、PRIMARY(最外层的 SELECT)、SUBQUERY(子查询)等。
  3. table:操作的表名。
  4. partitions:查询中涉及到的分区列表。
  5. type:表示用于执行查询的 Join 类型,例如 ALL,index,range,ref,eq_ref 等。
  6. possible_keys:可能用于查询的索引列表。
  7. key:实际使用的索引。
  8. key_len:表示索引字段长度。
  9. ref:表示索引和哪个字段或常量进行比较。
  10. rows:表示需要扫描的表行数。
  11. filtered:表示筛选出来的行占总行数的百分比。
  12. Extra:其他信息,如使用的索引类型、是否使用临时表、是否使用文件排序等。

四、按照优化程度从最好到最差的顺序排列:

  1. system:表示只有一行记录(例如SELECT ... FROM DUAL),这是最快的访问类型。
  2. const:表示通过索引一次就能找到的常量表达式。例如,根据主键或唯一索引进行等值查询。
  3. eq_ref:表示使用了等值连接,对于每个索引键值,表中只有一条匹配记录。这通常出现在使用主键或唯一索引进行连接的情况下。
  4. ref:表示使用非唯一索引进行等值查询或使用唯一索引进行不完全的索引查询。这可能返回多个匹配记录。
  5. range:表示通过索引范围扫描来获取记录,例如使用BETWEENIN或某些算术操作符进行查询。
  6. index:表示全索引扫描,通常出现在查询中没有使用索引或无法使用索引的情况下。
  7. all:表示全表扫描,需要遍历整个表以找到匹配的记录,这是最慢的访问类型。

五、SHOW INDEX指令

  • Table:表示所查询的表名。
  • Non_unique:表示索引是否允许重复值,如果为0则表示唯一索引,否则为非唯一索引。
  • Key_name:表示索引名称。
  • Seq_in_index:表示这个索引列在索引中出现的顺序,从1开始计数。
  • Column_name:表示索引列的名称。
  • Collation:表示索引列的字符集。
  • Cardinality:表示索引列的基数,即不同值的数量,数值越大则说明该索引是更加有用的。
  • Sub_part:表示索引列的子串长度,对于非字符串类型的索引列其值为null。
  • Packed:表示所有索引列使用的数据类型所占的字节数,数值越小则说明该索引更加紧凑。
  • Null:表示索引列是否允许为空。
  • Index_type:表示使用的索引方法,如 Btree、Hash 等。
  • Comment:表示索引的注释信息。

六、常用优化手段

1、删除单个索引,增加组合索引

2、修改处理时间条件的函数function_xx_month【针对SQL查询中使用函数处理】

3、改进重复数据集【针对帆软数据集重复、冗余问题】

4、将in子查询改为内连接

5、优化group by字段

6、开启缓存【如果SQL因业务场景是在无法继续优化,可以开启帆软数据集中的数据缓存,牺牲服务器的空间换取SQL执行的时间】

7、条件属性的删除【帆软报表中的条件属性、过滤、形态、公式计算比较多的时候需要考虑优化】

8、删除索引【过量的索引也会导致查询速度变慢】

9、将between and关键字换为>= <=【这个仁者见仁,自己测试部分场景下的SQL有显著提速,但是大多数情况下提速不明显】

七、总结

SQL的优化是一个不断试错的过程,同时观摩不同人的SQL风格,会有不一样的理解,如果你看的懂别人写的,静下心多看,这样自己写的时候,水到渠成,如果看不懂别人的SQL/代码,静下心慢慢看,只有看懂才会写!共勉!

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

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

相关文章

JDK的安装与配置

所有的开发&#xff0c;第一步必然是准备环境&#xff0c;而JDK提供了一套完整的工具和环境&#xff0c;使开发人员能够编写、编译和运行Java应用程序。是Java开发的基础&#xff0c;为开发者提供了丰富的功能和工具&#xff0c;简化了Java应用程序开发的过程。所以这里就记录一…

C++教程——vector容器、deque容器、stack容器、queue容器、list容器、set容器、map容器

vector容器 基本概念 vector赋值操作 vector容量和大小 vector插入与删除 vector数据存取 vector互换容器 vector预留空间&#xff1a;减少开辟内存空间的次数 deque容器 deque构造函数 deque赋值方式 deque大小操作 deque插入和删除 deque数据存取 deque排序 stack容器 stack…

iOS开发 - 系统自带框架实现扫一扫功能

iOS 扫一扫 利用系统自带框架实现扫一扫功能 一 项目配置 扫一扫功能相机和相册权限&#xff0c;在info.plist中设置询问用户是否允许访问的权限。 info.plist加入NSCameraUsageDescription、NSPhotoLibraryUsageDescription、NSPhotoLibraryAddUsageDescription <key&g…

java.lang.UnsatisfiedLinkError: Could not load SWT library.

java.lang.UnsatisfiedLinkError: Could not load SWT library. https://download.eclipse.org/windowbuilder/lastgoodbuild

力扣206. 反转链表

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 题解 方法一&#xff1a;类似头插法 设置3个指针cur、next、newhead&#xff0c;其中cur和next指向当前链表头…

Kubernetes基础知识点

k8s可以看做是一个集群操作系统&#xff0c;能够对容器进行调度和编排。 Kubernetes中的基本对象 pod 是k8s中的最小单位&#xff0c;一个pod封装一个或者多个容器&#xff0c;存储资源。 deployment 是对pod的服务化封装&#xff0c;可以包含一个或多个pod statefulset 为…

ArcGIS处理nc数据步骤

降水温度蒸散发等气象数据通常以NC格式存储&#xff0c;可以用Matlab和ArcGIS读取数据。常为逐年逐月逐日数据。在用GIS进行数据分析时&#xff0c;需要将其转换为栅格数据。 &#xff08;1&#xff09;打开nc数据。打开GIS, ArcToolbox-Multidimension Tools-Make NetCDF Rast…

多线程高频知识点—2023

多线程高频知识点—2023 多线程的基本概念什么是线程/进程为什么在进程中还需要线程呢&#xff1f;同步与异步的区别程序计数器多线程的应用场景多线程的创建方式手写一个异步日志框架多线程线程安全问题 多线程的基本概念 什么是cpu CPU的中文名称是中央处理器&#xff0c;是…

【优选算法】—— 滑动窗口类问题

本期&#xff0c;我给大家带来的是关于滑动窗口类算法的介绍&#xff0c;并通过具体的题目帮助大家思考理解。 目录 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;题目讲解 1、难度&#xff1a;medium 1️⃣长度最小的子数组 2️⃣找到字符串中所有字⺟…

Xcode 更新后 Version 14.3.1报错

File not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a Xode版本和pod版本不一致导致&#xff0c;改成一致就可以了 放在podfile文件里,最后一个pod,和最后一个end中间 Showing Recent …

将字符串转换为字典json.loads(字符串)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将字符串转换为字典 json.loads(字符串) [太阳]选择题 关于以下代码说法错误的是? import json myStr{"name":"xiaobai","age":30} print(【显示】mySt…

【论文阅读】TransCAM: Transformer Attention-based CAM Refinement for WSSS

分享一篇阅读的用于弱监督分割的论文 论文标题&#xff1a; TransCAM: Transformer Attention-based CAM Refinement for Weakly Supervised Semantic Segmentation 作者信息&#xff1a; 代码地址&#xff1a; https://github.com/liruiwen/TransCAM Abstract 大多数现有…

java判断某个字符串是否在字符串数组中的方法(4种)

1.效率最高&#xff08;最原始&#xff09; 代码如下&#xff08;示例&#xff09;&#xff1a; public class Demo { public static boolean useLoop(String[] arr, String targetValue) { for (String s : arr) { if (s.equals(targetValue)) return true; } return false; }…

图像分类——模型微调

目录 微调热狗识别获取数据集模型构建与训练 微调 热狗识别 获取数据集 import tensorflow as tf import pathlibtraindirhotdog/train testdirhotdog/test image_gentf.keras.preprocessing.image.ImageDataGenerator(rescale1/255) train_data_genimage_gen.flow_from_direc…

2023年Q2空调行业品牌数据榜单(京东商品数据)

随着夏季的来临&#xff0c;高温天气也带动部分家电行业的销售&#xff0c;以空调为代表的家电市场正逐步恢复活力。结合鲸参谋电商数据分析平台的相关数据&#xff0c;我们来分析一下2023年Q2空调市场的具体销售表现。 根据鲸参谋平台的数据显示&#xff0c;2023年4-6月份&am…

TypeScript学习(2)- ts基本类型

类型声明式Ts非常重要的一个特点&#xff0c;通过类型声明可以指定TS中变量&#xff08;参数&#xff0c;形参&#xff09;的类型。指定类型后&#xff0c;当为变量赋值时&#xff0c;ts编译器会自动检查值是否符合类型声明&#xff0c;符合则赋值&#xff0c;否则报错。 目录 …

从VAE到Diffusion生成模型详解(1):VAE

文章目录 1. 生成式模型简介2. PixelRNN/CNN3. VAE3.1 自编码器AE3.2 VAE基本原理3.3 VAE公式推导 4. 参考 1. 生成式模型简介 什么是生成式模型 给定训练集&#xff0c;产生与训练集同分布的新样本。如下图所示&#xff0c;希望学习到一个模型 p m o d e l ( x ) p_{model}(…

22 分页控件

文章目录 界面设置初始化主对话框子页面初始化 页面1枚举窗口页面2枚举进程全部代码 界面设置 ui 设置 >创建CTablCtrl > 创建页控件&#xff08;子窗口&#xff09;&#xff0c;style设置成为chlid 添加类 页面中加入listCtrl 控件 添加变量 分别添加初始化函数 初始化…

举例说明单层神经网络的工作原理

假设我们有一个简单的单层神经网络&#xff0c;用于解决一个简单的问题&#xff1a;根据一个人的年龄&#xff08;x&#xff09;来预测其收入&#xff08;y&#xff09;。在这个例子中&#xff0c;输入数据只有一个特征&#xff08;年龄&#xff09;&#xff0c;因此我们可以用…

Can转以太网网关can协议转以太网协议

YC-ETH-CAN-2 是一款用来把 CAN 总线数据转为网口数据的设备。网口支持 TCP Sever、TCP Client、UDP Sever、UDP Client、UDP Broadcast 模式&#xff0c;可以通过软件配置和网页配置。 设备提供两路 CAN 接口&#xff0c;两路 CAN 可分别配置为不同的工作模式&#xff0c;独立…