SQL调优教程

SQL调优教程

基础方法论

任何计算机应用系统性能问题最终都可以归结为
1.cpu消耗
2.内存使用
3.对磁盘,网络或其他I/O设备的输入/输出(I/O)操作
遇到性能问题时,要判断的第一点就是“在这三种资源中,是否有哪一种资源达到了有问题的程度”,因为这一点能指导我们搞清楚“需要优化重构什么”和“如何优化重构它”

sql调优领域

应用程序级调优包括:
1.sql语句调优
2.管理变化调优实例级调优
1.内存
2.数据结构
3.实例配置操作系统交互
1.I/O
2.swap
3.Parameters

sql优化方法

1.优化业务数据
2.优化数据设计
3.优化流程设计
4.优化sql语句
5.优化物理结构
6.优化内存分配
7.优化I/O
8.优化内存竞争
9.优化操作系统

sql优化过程

1.定位有问题的语句
2.检查执行计划
3.检查执行计划中优化器的统计信息
4.分析相关表的记录数、索引情况
5.改写sql语句、使用HINT、调整索引、表分析
6.有些sql语句不具备优化的可能,需要优化处理方式
7.达到最佳执行计划

什么是好的sql语句

1.尽量简单,模块化
2.易读,易维护
3.节省资源(内存/cpu/扫描的数据块要少/少排序)
4.不造成死锁

sql语句的处理过程

sql语句的四个处理阶段:解析(PARSE):
检查语法
检查语义和相关的权限
在共享池中查找sql语句
合并(MERGE)视图定义和子查询
确定执行计划绑定(BIND)
在语句中查找绑定变量
赋值(或重新赋值)执行(EXECUTE)
应用执行计划
执行必要的I/O和排序操作提取(FETCH)
从查询结果中返回记录
必要时进行排序
使用ARRAY FETCH机制

请添加图片描述

sql表的基本连接方式

sql表连接分成外连接、内连接和交叉连接

请添加图片描述

外连接

外连接可分为:左连接、右连接、完全外连接

1、左连接 left join或left outer join

SQL语句:select * from student left join course onstudent.ID=course.ID

左外连接包含left join左表所有行,如果左表中某行在右表没有匹配,则结果中对应行右表的部分全部为空(NULL).

注:此时我们不能说结果的行数等于左表数据的行数。当然此处查询结果的行数等于左表数据的行数,因为左右两表此时为一对一关系

2、右连接 right join或right outer join

SQL语句:select * from student right join course on student.ID=course.ID

右外连接包含right join右表所有行,如果左表中某行在右表没有匹配,则结果中对应左表的部分全部为空(NULL)

注:同样此时我们不能说结果的行数等于右表的行数。当然此处查询结果的行数等于左表数据的行数,因为左右两表此时为一对一关系。

3、完全外连接 full join或full outer join

SQL语句:select * from student full join course on student.ID=course.ID

完全外连接包含fulljoin左右两表中所有的行,如果右表中某行在左表中没有匹配,则结果中对应行右表的部分全部为空(NULL),如果左表中某行在右表中没有匹配,则结果中对应行左表的部分全部为空(NULL)

内连接

内连接 join 或inner join

SQL语句:select * from student inner join course on student.ID=course.ID

inner join是比较运算符,只返回符合条件的行。

此时相当于:select * fromstudent,course where student.ID=course.ID

交叉连接

交叉连接cross join

SQL语句:select * from student cross join course

概念:没有WHERE子句的交叉联接将产生连接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小

如果我们在此时给这条SQL加上WHERE子句的时候比如SQL:select * from student cross join course where student.ID=course.ID ,此时将返回符合条件的结果集,结果和inner join所示执行结果一样.

sql优化最佳实践

选择最有效率的表连接顺序

首先要明白一点就是SQL的语法顺序和执行顺序是不一致的SQL的语法顺序:select  【distinct】....from ....【xxx  join】【on】....where....group by ....having....【union】....order by......SQL的执行顺序:from ....【xxx  join】【on】....where....group by ....avg()、sum()....having....select  【distinct】....order by......from子句--执行顺序为从后往前、从右到左
表名(最后面的那个表名为驱动表,执行顺序为从后往前,所以数据量较少的表尽量放后)where子句--执行顺序为自下而上、从右到左
将可以过滤掉大量数据的条件写在where的子句的末尾性能最优group by和order by子句执行顺序都为从左到右select子句--少用*号,尽量取字段名称。 使用列名意味着将减少消耗时间

避免产生笛卡尔积

含有多表的sql语句,必须指明各表的连接条件,以避免产生笛卡尔积。N个表连接需要N-1个连接条件

避免使用*

当你想在select子句中列出所有的列时,使用动态sql列引用“*”是一个方便的方法,不幸的是,是一种非常低效的方法。sql解析过程中,还需要把“*”依次转换为所有的列名,这个工作需要查询数据字典完成

用where子句替换having子句

where子句搜索条件在进行分组操作之前应用;而having子句条件在进行分组操作之后应用。避免使用having子句,having子句只会在检索出所有纪录之后才对结果集进行过滤,这个处理需要排序,总计等操作。如果能通过where子句限制记录的数目,那就能减少这方面的开销。

用exists、not exists和in、not in相互替代

原则是哪个的子查询产生的结果集小,就选哪个select * from t1 where x in (select y from t2)select * from t1 where exists (select null from t2 where y =x)IN适合于外表大而内表小的情况;exists适合于外表小而内表大的情况

使用exists替代distinct

当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在select子句中使用distinct,一般可以考虑使用exists代替,exists使查询更为迅速,因为子查询的条件一旦满足,立马返回结果。低效写法:select distinct dept_no,dept_namefrom dept d,emp e where d.dept_no=e.dept_no高效写法:select dept_no,dept_name from dept d where  exists (select 'x' from emp e where e.dept_no=d.dept_no)备注:其中x的意思是:因为exists只是看子查询是否有结果返回,而不关心返回的什么内容,因此建议写一个常量,性能较高!用exists的确可以替代distinct,不过以上方案仅适用dept_no为唯一主键的情况,如果要去掉重复记录,需要参照以下写法:select * from emp  where dept_no exists (select Max(dept_no)) from dept d, emp e where e.dept_no=d.dept_no group by d.dept_no)

避免隐式数据类型转换

隐式数据类型转换不能适用索引,导致全表扫描!t_tablename表的phonenumber字段为varchar类型以下代码不符合规范:select column1 into i_l_variable1 from t_tablename where phonenumber=18519722169;应编写如下:select column1 into i_lvariable1 from t_tablename where phonenumber='18519722169';

使用索引来避免排序操作

在执行频度高,又含有排序操作的sql语句,建议适用索引来避免排序。
排序是一种昂贵的操作,在一秒钟执行成千上万次的sql语句中,如果带有排序操作,往往会消耗大量的系统资源,性能低下。
索引是一种有序结果,如果order by后面的字段上建有索引,将会大大提升效率

尽量使用前端匹配的模糊查询

例如,column1 like 'ABC%'方式,可以对column1字段进行索引范围扫描;而column1 kike '%ABC%'方式,即使column1字段上存在索引,也无法使用该索引,只能走全表扫描

不要在选择性较低的字段建立索引

在选择性较低的字段使用索引,不但不会降低逻辑I/O,相反,往往会增加大量逻辑I/O降低性能。比如,性别列,男和女

避免对列的操作

不要在where条件中对字段进行数学表达式运算,任何对列的操作都可能导致全表扫描,
这里所谓的操作,包括数据库函数,计算表达式等等,
查询时要尽可能将操作移到等式的右边,甚至去掉函数例如:下列sql条件语句中的列都建有恰当的索引,但几十万条数据下已经执行非常慢了:select * from record where amount/30(1000 (执行时间11s)由于where子句中对列的任何操作结果都是在sql运行时逐行计算得到,因此它不得不进行全表扫描,而没有使用上面的索引;如果这些结果在查询编译时就能得到,那么就可以被sql优化器优化,使用索引,避免全表扫描,因此sql重写如下:select * from record where amount(1000*30 (执行时间不到1秒)

尽量去掉"IN",“OR”

含有"IN"、"OR"的where子句常会使用工作表,使索引失效,如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引;select count(*) from stuff where id_no in('0','1')可以拆开为:select count(*) from stuff where id_no='0'select count(*) from stuff where id_no='1'然后在做一个简单的加法

尽量去掉"(>"

尽量去掉"(>",避免全表扫描,如果数据是枚举值,且取值范围固定,可以使用"or"方式update serviceinfo set state=0 where state(>0;以上语句由于其中包含了"(>",执行计划中用了全表扫描(Table accessfull),没有用到state字段上的索引,实际应用中,由于业务逻辑的限制,字段state只能是枚举值,例如0,1或2,因此可以去掉"(>"利用索引来提高效率。update serviceinfo set state=0 where state =1 or state =2

避免在索引列上使用IS NULL或者IS NOT NULL

避免在索引中使用任何可以为空的列,导致无法使用索引

批量提交sql

如果你需要在一个在线的网站上去执行一个大的DELETE或INSERT查询,你需要非常小心,要避免你的操作让你的整个网站停止响应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。Apache会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程或线程,数据库链接,打开的文件数,可能不仅仅会让你的WEB服务崩溃,还可能会让你的整台服务器马上挂了。所以,如果你有一个大的处理,你一定把其拆分

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

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

相关文章

Linux环境下Elasticsearch相关软件安装

Linux环境下Elasticsearch相关软件安装 本文将介绍在linux(Centos7)环境下安装Elasticsearch相关的软件。 1、安装Elasticsearch 1.1 Elasticsearch下载 首先去Elasticsearch官网下载相应版本的安装包,下载之后传输到linux服务器上。 官网地址:http…

Python采集某网站小视频内容, m3u8视频内容下载

目录标题 前言环境使用:模块使用:代码实现步骤代码展示尾语 前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 环境使用: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 模块使用: import requests >>> pip install requests 内置模块 你安装好python环境就…

Windows 微信更新内核(小程序框架)的指南

WMPF-PC 更新指引: 准备工作 1. 安装最新微信客户端( https://dldir1.qq.com/weixin/Windows/WeChatSetup.exe ) 2. 在微信在搜索栏输入:showcmdwnd (包括前面冒号) 中输入以下代码以开启 wmpf 新内核版本(已经是现网默认,可以…

安装redis,适配阿里云服务器,Liunx安装redis

下载redis以及编译安装 下载redis文件 wget http://download.redis.io/releases/redis-6.0.8.tar.gz #下载redis压缩文件 tar xzf redis-6.0.8.tar.gz #解压缩 cd redis-6.0.8 make 查看是否安装了gcc编译输入gcc --version如果没有…

对比CahtGPT Bard Claude2对中文的理解

对比CahtGPT Bard Claude2对中文的理解 今天简单测试了一下目前这三个很火的模型对中文的理解能力 简单问题 鲁迅和周树人的关系 Bard CahtGPT Claude 介绍一下平凡的世界这本书 Bard CahtGPT

5.CSS(二)

目录 一、Emmet语法 (一)快速生成HTML结构语法 (二)快速生成CSS样式语法 二、CSS的复合选择器 (一)后代选择器(重要) (二)子选择器(重要&…

什么是Java中的JVM(Java虚拟机)?

JVM(Java虚拟机)是Java平台的核心组件之一,是一个用于执行Java字节码的虚拟计算机。Java源代码经过编译器编译,生成字节码文件(.class文件),然后由JVM来解释和执行这些字节码。JVM负责将字节码翻…

kafka消息监听

1,spring配置kafka网址 2,listener Component public class OrderMsgListener {KafkaListener(topics "order",groupId "order-service")public void listen(ConsumerRecord record){System.out.println("收到消息&#xf…

Upload文件导入多条数据到输入框

需求场景:文本框内容支持批量导入(文件类型包括’.txt, .xls, .xlsx’)。使用AntD的Upload组件处理。 下面是Upload的配置(伪代码),重点为beforeUpload中的逻辑 // Antd 中用到的Upload组件 import { UploadOutlined } from ant…

静态路由小实验

文章目录 一、实验要求及拓扑图二、实验步骤三、思考题 一、实验要求及拓扑图 二、实验步骤 1、创建VLAN,将端口划入vlan 在交换机S3、S4上创建VLAN10、20 Switch(config)#vl 10 Switch(config-vlan)#vl 20 S3(config)#int f0/3 S3(config-if)#switchport access …

vue3 实现排序按钮

需求背景解决效果index.vue 需求背景 需要实现一个复用性&#xff0c;是提供表单顺倒排序的按钮 解决效果 index.vue <!--/*** author: liuk* date: 2023/7/25* describe: 排序按钮*/--> <template><div class"sort-fn"><span :class"[…

一次线上OOM问题的个人复盘

我们一个java服务上线后&#xff0c;偶尔会发生内存OOM(Out Of Memory)问题&#xff0c;但由于OOM导致服务不响应请求&#xff0c;健康检查多次不通过&#xff0c;最后部署平台kill了java进程&#xff0c;这导致定位这次OOM问题也变得困难起来。 最终&#xff0c;在多次review代…

electron的electron-packager打包运行和electron-builder生产安装包过程,学透 Electron 自定义 Dock 图标

electron的electron-packager打包运行和electron-builder生产安装包过程 开发electron客户端程序&#xff0c;打包是绕不开的问题。 macOS 应用构建&#xff0c;看似近在咫尺&#xff0c;实则坑坑致命。 场景&#xff1a;mac笔记本打包&#xff0c;以及生产出可交付的软件安装…

什么是事件循环Event Loop

一、含义 事件循环是指不断从任务队列中取出任务&#xff0c;并执行其对应的回调函数的过程。 二、事件循环流程 1.主线程执行同步任务&#xff0c;直到遇到异步任务时&#xff0c;将其回调函数他家到任务队列中&#xff0c;然后继续执行同步任务 2.当所有同步任务执行完之后&a…

如何利用plotly和geopandas根据美国邮政编码(Zip-Code)绘制美国地图

对于我自己来说&#xff0c;该需求源自于分析Movielens-1m数据集的用户数据&#xff1a; UserID::Gender::Age::Occupation::Zip-code 1::F::1::10::48067 2::M::56::16::70072 3::M::25::15::55117 4::M::45::7::02460 5::M::25::20::55455 6::F::50::9::55117我希望根据Zip-…

在 3ds Max 和 After Effects 中创建逼真的蜘蛛网模型

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 创建蜘蛛网 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 转到创建>标准基元>平面并创建一个平面 在前视图中。 创建平面 步骤 3 保持其长度和宽度 segs 为 80。 段 步骤 4 打开修改器列表…

Python爬虫之Scrapy框架系列(23)——分布式爬虫scrapy_redis浅实战【XXTop250部分爬取】

目录&#xff1a; 1.实战讲解&#xff08;XXTop250完整信息的爬取&#xff09;&#xff1a;1.1 使用之前做的完整的XXTOP250项目&#xff0c;但是设置为只爬取一页&#xff08;共25个电影&#xff09;,便于观察1.2 配置settings文件中使用scrapy_redis的必要配置&#xff0c;并…

智能汽车的主动悬架工作原理详述

摘要&#xff1a; 本文将详细介绍主动悬架功能原理设计。 主动悬架是车辆上的一种汽车悬架。它使用车载系统来控制车轮相对于底盘或车身的垂直运动&#xff0c;而不是由大弹簧提供的被动悬架&#xff0c;后者的运动完全由路面决定。主动悬架分为两类&#xff1a;真正的主动悬架…

fSGAT批量候选基因关联分析丨快速单基因关联分析

候选基因如何分析&#xff1f; 通常情况下关联分析会得到一大堆候选基因&#xff0c;总不可能每个都有用&#xff0c;因此需要对候选基因进行深一步分析&#xff0c;本篇笔记分享一下群体遗传学研究中GWAS候选位点与候选基因的筛选思路。主要的方式包括单基因关联分析、连锁程度…

ubuntu 静态IP设置

ubuntu 静态IP设置&#xff1a; 1.输入&#xff1a; sudo vim /etc/netplan/01-network-manager-all.yaml Let NetworkManager manage all devices on this system network: ethernets: ens33: dhcp4: no addresses: [192.168.1.119/24] gateway4: 192.168.1.1 nameservers: …