一、开门见山,问题所在

sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种情况。

  • 网速不给力,不稳定。
  • 服务器内存不够,或者SQL 被分配的内存不够。
  • sql语句设计不合理
  • 没有相应的索引,索引不合理
  • 没有有效的索引视图
  • 表数据过大没有有效的分区设计
  • 数据库设计太2,存在大量的数据冗余
  • 索引列上缺少相应的统计信息,或者统计信息过期
  • ....

那么我们如何给找出来导致性能慢的的原因呢?

  • 首先你要知道是否跟sql语句有关,确保不是机器开不开机,服务器硬件配置太差,没网你说p啊
  • 接着你使用我上一篇文章中提到的2柯南sql性能检测工具--sql server profiler,分析出sql慢的相关语句,就是执行时间过长,占用系统资源,cpu过多的
  • 然后是这篇文章要说的,sql优化方法跟技巧,避免一些不合理的sql语句,取暂优sql
  • 再然后判断是否使用啦,合理的统计信息。sql server中可以自动统计表中的数据分布信息,定时根据数据情况,更新统计信息,是很有必要的
  • 确认表中使用啦合理的索引,这个索引我前面博客中也有提过,不过那篇博客之后,还要进一步对索引写篇文章
  • 数据太多的表,要分区,缩小查找范围

二、分析比较执行时间计划读取情况

select * from dbo.Product

执行上面语句一般情况下只给你返回结果和执行行数,那么你怎么分析呢,怎么知道你优化之后跟没有优化的区别呢。

下面给你说几种方法。

1.查看执行时间和cpu占用时间

set statistics time onselect * from dbo.Productset statistics time off

打开你查询之后的消息里面就能看到啦。

2.查看查询对I/0的操作情况

set statistics io onselect * from dbo.Productset statistics io off

执行之后

  • 扫描计数:索引或表扫描次数
  • 逻辑读取:数据缓存中读取的页数
  • 物理读取:从磁盘中读取的页数
  • 预读:查询过程中,从磁盘放入缓存的页数
  • lob逻辑读取:从数据缓存中读取,image,text,ntext或大型数据的页数
  • lob物理读取:从磁盘中读取,image,text,ntext或大型数据的页数
  • lob预读:查询过程中,从磁盘放入缓存的image,text,ntext或大型数据的页数

如果物理读取次数和预读次说比较多,可以使用索引进行优化。

如果你不想使用sql语句命令来查看这些内容,方法也是有的,哥教你更简单的。

查询--->>查询选项--->>高级

被红圈套上的2个选上,去掉sql语句中的set statistics io/time on/off 试试效果。哦也,你成功啦。。

3.查看执行计划,执行计划详解

选中查询语句,点击

然后看消息里面,会出现下面的图例

首先我这个例子的语句太过简单,你整个复杂的,包涵啊。

分析:鼠标放在图标上会显示此步骤执行的详细内容,每个表下面都显示一个开销百分比,分析站百分比多的的一块,可以根据重新设计数据结构,或这重写sql语句,来对此进行优化。如果存在扫描表,或者扫描聚集索引,这表示在当前查询中你的索引是不合适的,是没有起到作用的,那么你就要修改完善优化你的索引。

三、select查询艺术

1.保证不查询多余的列与行。

尽量避免select * 的存在,使用具体的列代替*,避免多余的列

使用where限定具体要查询的数据,避免多余的行

使用top,distinct关键字减少多余重复的行

2.慎用distinct关键字

distinct在查询一个字段或者很少字段的情况下使用,会避免重复数据的出现,给查询带来优化效果。

但是查询字段很多的情况下使用,则会大大降低查询效率。

由这个图,分析下:

很明显带distinct的语句cpu时间和占用时间都高于不带distinct的语句。原因是当查询很多字段时,如果使用distinct,数据库引擎就会对数据进行比较,过滤掉重复数据,然而这个比较,过滤的过程则会毫不客气的占用系统资源,cpu时间。

3.慎用union关键字

此关键字主要功能是把各个查询语句的结果集合并到一个结果集中返回给你。用法

unionunion...

满足union的语句必须满足:1.列数相同。 2.对应列数的数据类型要保持兼容。

执行过程:

依次执行select语句-->>合并结果集--->>对结果集进行排序,过滤重复记录。

select * from((orde o left join orderproduct op on o.orderNum = op.orderNum) inner join product p on op.proNum = p.productnum) where p.id < 10000unionselect * from((orde o left join orderproduct op on o.orderNum = op.orderNum) inner join product p on op.proNum = p.productnum) where p.id < 20000 and p.id >= 10000unionselect * from((orde o left join orderproduct op on o.orderNum = op.orderNum) inner join product p on op.proNum = p.productnum) where p.id > 20000-- -这里可以写p.id > 100 结果一样, 因为他筛选过啦 -- -- -- -对比上下两个语句-- -- -- -- select * from((orde o left join orderproduct op on o.orderNum = op.orderNum) inner join product p on op.proNum = p.productnum)

由此可见效率确实低,所以不是在必要情况下避免使用。其实有他执行的第三部:对结果集进行排序,过滤重复记录。就能看出不是什么好鸟。然而不对结果集排序过滤,显然效率是比union高的,那么不排序过滤的关键字有吗?答,有,他是union all,使用union all能对union进行一定的优化。。

4.判断表中是否存在数据

select count(*) from product select top(1) id from product

很显然下面完胜

5.连接查询的优化

首先你要弄明白你想要的数据是什么样子的,然后再做出决定使用哪一种连接,这很重要。

各种连接的取值大小为:

内连接结果集大小取决于左右表满足条件的数量

左连接取决与左表大小,右相反。

完全连接和交叉连接取决与左右两个表的数据总数量

select * from ( (select * from orde where OrderId>10000) o left join orderproduct op on o.orderNum=op.orderNum )select * from ( orde o left join orderproduct op on o.orderNum=op.orderNum )where o.OrderId>10000

由此可见减少连接表的数据数量可以提高效率。

四、insert插入优化

--创建临时表create table# tb1 ( id int, name nvarchar(30), createTime datetime )declare@ i intdeclare@ sql varchar(1000)set@ i = 0while (@i < 100000) --循环插入10w条数据beginset@ i = @i + 1set@ sql = ' insert into #tb1 values ('+convert(varchar(10),@i)+', '' erzi '+ convert(nvarchar(30), @i) + '' ',' '' + convert(nvarchar(30), getdate()) + '' ')' exec(@sql) end

我这里运行时间是51秒

--创建临时表create table# tb2 ( id int, name nvarchar(30), createTime datetime )declare@ i intdeclare@ sql varchar(8000)declare@ j intset@ i = 0while (@i < 10000) --循环插入10w条数据beginset@ j = 0set@ sql = ' insert into #tb2 select ' + convert(varchar(10), @i * 100 + @j) + ',''erzi' + convert(nvarchar(30), @i * 100 + @j) + ''',''' + convert(varchar(50), getdate()) + ''''set@ i = @i + 1while (@j < 10) beginset@ sql = @sql + ' union all select ' + convert(varchar(10), @i * 100 + @j) + ',''erzi '+convert(nvarchar(30),@i*100+@j)+''','''+convert(varchar(50),getdate())+''''set@ j = @j + 1endexec(@sql)enddrop table# tb2select count(1) from# tb2

我这里运行时间大概是20秒

分析说明:insert into select批量插入,明显提升效率。所以以后尽量避免一个个循环插入。

五、优化修改删除语句

如果你同时修改或删除过多数据,会造成cpu利用率过高从而影响别人对数据库的访问。

如果你删除或修改过多数据,采用单一循环操作,那么会是效率很低,也就是操作时间过程会很漫长。

这样你该怎么做呢?

折中的办法就是,分批操作数据。

delete product where id<1000delete product where id>=1000 and id<2000delete product where id>=2000 and id<3000.....

当然这样的优化方式不一定是最优的选择,其实这三种方式都是可以的,这要根据你系统的访问热度来定夺,关键你要明白什么样的语句是什么样的效果。

总结:优化,最重要的是在于你平时设计语句,数据库的习惯,方式。如果你平时不在意,汇总到一块再做优化,你就需要耐心的分析,然而分析的过程就看你的悟性,需求,知识水平啦。

Java肖先生:专注于Java开发技术的研究与知识分享!

————END————

  • 点赞(编辑不易,感谢您的支持)
  • ...
  • 转发(分享知识,传播快乐)
  • ...
  • 关注(每天更新Java开发技术)
  • ...

推荐阅读

看到网上疯传的《阿里Java架构师成长之路》,网友瞬间沸腾了

Java程序员备战“金九银十”必备的面试技巧(附阿里Java岗面试题)

navicat循环执行上下两行相减sql语句_SQL语句的优化分析相关推荐

  1. navicat循环执行上下两行相减sql语句_SQL太难?你离完全理解SQL就差这10步!

    - 点击上方"中国统计网"设置⭐星标不迷路!- 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语 ...

  2. pandas 中上下两行相减(隔行相减) -- shift函数的使用

    pandas 中上下两行相减(隔行相减) -- shift函数的使用 最近使用pandas处理数据,需求是想相邻两行上下相减,查API发现shift函数,很灵活,.你也可以隔任意行相减. p['xx_ ...

  3. java for loop_Java for循环执行了两次

    我在执行for循环时遇到了一些麻烦.循环被调用两次.以下是完成工作的代码: import java.util.ArrayList; import java.util.List; public clas ...

  4. mysql种default约束的语句_sql语句大全之SQL DEFAULT 约束

    SQL DEFAULT约束 DEFAULT 约束用于向列中插入默认值. 如果没有规定其他的值,那么会将默认值添加到所有的新纪录. SQL DEFAULT Constraint on CREATE TA ...

  5. laravel打印sql语句_SQL语句为什么慢?索引为什么失效?

    为什么你写的sql查询慢?为什么你建的索引常失效?通过本篇内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引, ...

  6. Hive实现将分组取top2的数据进行相减(SQL面试题)

    1.问题描述 一张成绩表class有如下字段,班级ID,英语成绩,数学成绩,语文成绩 id    english   math  chinese classid                     ...

  7. python 数据错位相减,上下两行相减

    今天接到一个需求,要求对数据错位相减.感觉写得有点麻烦,如果有其他方法,欢迎留言交流 数据说明:有客户.消费日期.消费额度 求解目标:对于同一个客户,对日期升序排序,如果下一个日期的消费额度大于上一个 ...

  8. c语言解析sql语句_sql语句面试50题(Mysql版附解析)

    本人最近在自学sql,从开始学到自己写完本练习50题大概花了12天的时间. 学习路径:<sql基础教程>第1遍(3天)→知乎中的sql网课+leetcode刷题(4天)→牛客网刷题(2天) ...

  9. declare sql语句_SQL语句大全【第二部分】技巧+经典案例

    - 点击上方"中国统计网"设置⭐星标不迷路!- 1 技巧 1.1=1,1=2的使用,在SQL语句组合时用的较多 "where 1=1" 是表示选择全部    & ...

最新文章

  1. BZOJ2120 数颜色 【带修改莫队】
  2. 分布式缓存系统 Memcached CAS协议
  3. 详析VC中坐标系的建立
  4. Linux操作系统下软件的安装方法大全
  5. Python sorted 和 sort() 的区别
  6. 南京计算机审计行业工资,南京最新各行业平均工资曝光!看完分分钟想跳槽!...
  7. 蛮力法 字符串匹配
  8. 我发现很多人嘴里喊着要赚钱
  9. sql limit 子句_具有并行性SQL Server TOP子句性能问题
  10. 【随笔】hi3531D 音频
  11. 三星 安装程序无法将 配置为此计算机,三星手机怎么安装软件 三星手机无法安装软件解决办法...
  12. 华为四核处理器K3V2
  13. python爬取京东商品信息_python爬虫:爬取京东商品信息
  14. [国家集训队]Tree I
  15. SCI声学期刊名以及影响因子
  16. 浙大版《C语言程序设计(第4版)》题目集 练习5-3 字符金字塔 (15 分)
  17. RC延时电路简要分析
  18. Python将文字转成语音并读出来
  19. python中screen用法_screen命令的使用
  20. Agilent/安捷伦81134A脉冲信号发生器

热门文章

  1. 程序员过关斩将--你为什么还在用存储过程?
  2. iNeuOS云操作系统,.NET Core全系打造
  3. ASP.NET Core MVC 视图
  4. 收起.NET程序的dll来
  5. 用StyleCop规范团队代码
  6. ASP.NET Core 3.0 项目开始“瘦身”
  7. 【DevOps+LIVE】直播复盘 – DevOps能力成长模型2018首发
  8. 手把手引进门之 ASP.NET Core Entity Framework Core(官方教程翻译版 版本3.2.5)
  9. .NET下使用HTTP请求的正确姿势
  10. C#使用Xamarin开发可移植移动应用进阶篇(7.使用布局渲染器,修改默认布局),附源码