SQL语句调优三板斧

改装有顺序------常开的爱车下手

   你的系统中有成千上万的语句,那么优化语句从何入手呢 ? 当然是系统中运行最频繁,最核心的语句了。废话不多说,上例子:

   

   这是一天的语句执行情况,里面柱状图表示的是对应执行时间段内语句的次数,总体看起来长时间语句非常多。

   下面看一下具体的语句执行情况:

   

   排位第一的语句执行次数38508次,是一个存储过程(RPC:Completed 表示存储过程结束,不知道这个的请看profiler的使用说明)。其中的一条语句(SP:StmtCompleted)也就是排在第二位的语句,存储过程的执行时间大部分消耗这条子语句上!

这个例子可以看出业务系统中使用最频繁,且远远高于其他处理的语句就是这个执行3W8Q多次的语句。

   那么看到这样的数据,想做优化当然要从这条语句下手了!它就是你最常开的车了! 这个例子中只要解决了这条语句的性能问题,整个系统性能就可以有一个质的飞跃。

--------------------------------上面的情况,你很专一,只喜欢开一种车!----------------------------

   这个例子中,你喜欢开的车就比较多了,也就是说需要你关注,并且优化的语句较多。(很多语句执行次数都很频繁,也就是系统中使用到的频繁功能较多)

   

   

   系统优化需要循序渐进,从系统最频繁的语句出发,逐个解决语句问题。

   有人看到这会说,博主你有工具,能收集、能统计,我啥也没有咋整?不要急后文脚本都会奉上!

改装前的知识储备

  知识储备很重要,语句的优化涉及的地方很多很多,要么为什么说可以写本书呢?

  1. 你知道什么是执行计划么?如何在语句执行的同时,看到执行计划?
  2. 你知道索引有几种?有什么区别么?
  3. 你知道有索引和没索引,语句执行的区别么?
  4. 你知道什么是统计信息么?
  5. 你知道什么是临时表,表变量,CTE?有什么区别?
  6. 什么是事务?什么是隔离级别?
  7. 你知道什么是逻辑读,什么是物理读,什么是预读么?怎么查看你执行消耗的IO资源?
  8. 你知道什么是等待?怎么查看你运行的语句是否在等待?等待反应出的问题是什么?
  9. 你了解SQL的锁机制么?
  10. 你了解TempDB么?什么样的语句会使用TempDB?
  11. 编译与重编译?
  12. 查询提示是干什么的?
  13. .....
  14. .....
  15. .....
  16. .....

常见的改装方式

------------------------------------新手区-----------高手勿进-------------------------------------  

  是不是就没法短时间内,掌握大部分语句的优化技巧呢? 这是可以的,简单介绍一下语句简单粗暴的调优方式:

  

开启执行计划,让执行计划告诉你,语句慢的原因

  

透过计划,一眼看出索引

   

   当语句执行后,执行计划中会提示你这条运行的语句中是否缺少索引,右键绿色部分"缺少索引提示",点击缺少索引详细信息,生成对应的索引脚本,创在在数据库中。

   在次执行语句验证是否有效,如果还继续提示索引缺失,继续按照此方法创建索引。

   

   索引对于一个语句的影响很大,一个有效的索引可以缩短语句的执行时间,并且降低CPU、IO、内存等消耗。也就是说不但让你的语句执行快,更降低了宝贵的系统资源消耗!

   执行计划中除了可以看出缺失的索引,也可以看出语句的主要消耗在哪。知道了主要消耗,我们也就可以针对这个消耗进行优化。如例子中94%的开销在表的扫描上。当看到这个开销很大并且是一个扫描的时候,第一反应要看扫描的表,有没有筛选条件“where”条件,或 “关联条件join" 如果有条件,那就看为什么没有先用条件过滤数据!是不是没有索引? 是不是创建的索引不能用(隐式转换?列上有函数?等等,具体为什么不能使用索引,请自行百度)

   高能提示:不要小看索引,感觉这都是小儿科。在我亲身经历的众多客户之中,大面积缺少索引的系统可以占到三层以上。或是软件开发完,对数据库就没有建立索引,或是随着系统的日积月累,数据量、功能也随之增加,系统得不到一个及时的跟踪优化导致。

    

降低语句的复杂度

  讲一个我自己的故事,我刚从业的时候对数据库的优化了解不深,一度认为自己写的SQL 好牛逼,因为现在给我,我真是看不懂。一个语句两张A4纸都打印不下!各种子查询,视图嵌套,函数嵌套,UNION ALL等等等。

不能否认这种语句写出来以后,有种小自豪感!因为别人根本看不懂,改也改不了!这种语句在对于SQL 的优化器来说就是灾难,下面简单的说下优化器拿到一条语句怎么样作出执行计划:

  首先传入一个语句,如果有视图,则会把你视图内的代码和外层代码经过二次编译变成一个大语句(多层视图都会编译成一个),然后从表连接开始,优化器会根据统计信息,和一些预查询(如执行所需要的字段类型长度,数据量等)针对你的条件选用一个表作为驱动表,然后继续和其他的表关联,并选用关联方式(hash、merge、nested loop)等,每次关联顺序和方式的都基于SQL的预估,也就是关联的越多,最后的预估可能越不准确,进而导致选用一个比较差的计划。为什么有好的不选却选出一个差的呢?因为优化器不会把你所有执行的可能都验证一次,然后选择一个最好的。这里选出来的“最优”的只是一个相对值。

  介绍的有点跑题了,下面我们说一下降低语句复杂度的常用方式:最常用的就是临时表,比如先把条件筛选性较强的几张表关联,然后把结果放入临时表,在用临时表和其他表关联。可以理解成我有10张表关联,我先拿5张表出来关联,然后把结果放入临时表,再跟另外5张表关联。这样这个查询的复杂度由10张表的联合变成 5+6,这样降低了复杂语句复杂度。

  复杂视图也是如此,在视图和外层关联前,放入临时表,再跟外层关联。

  子查询也是如此,可以分离出来成为临时表的子查询,先分离出来。

  

  情况很多种,最终目的就是降低语句复杂性,让语句分多个步骤执行,这样也可以让优化器每次选出一个比较稳定的计划(一个语句执行有时快有时慢,也很可能是语句的复杂性导致的)。

  

  高能提示:部分系统核心处理的语句比较复杂,且已经很多年前留下的遗产了,经历了一代又一代,我真心不敢碰。那么恭喜你中奖了,好好分析下业务,通过临时表拆分语句还是有可能的!

       临时表和表变量,最大的区别是表变量作为中间过程表不能插入太多数据,如果数据插入的多严重影响性能。

降低并行度,使用并行提升性能

  这个小标题好像有些矛盾!解释一下降低并行度是因为现在的服务器配置CPU数都很大64或更多的随处可见,系统选用并行计划时,使用过多的CPU 反而会使性能下降具体请参见:Expert 诊断优化系列------------------你的CPU高么?

  首先看一个等待: CXPACKET

  

   

   CXPACKET 是最常见的等待之一,等待 并行计划 CPU的调度,或线程上的资源等待,请参见

   你的系统中有成千上万的语句,那么优化语句从何入手呢 ? 当然是系统中运行最频繁,最核心的语句了。废话不多说,上例子:

   

   这是一天的语句执行情况,里面柱状图表示的是对应执行时间段内语句的次数,总体看起来长时间语句非常多。

   下面看一下具体的语句执行情况:

   

   排位第一的语句执行次数38508次,是一个存储过程(RPC:Completed 表示存储过程结束,不知道这个的请看profiler的使用说明)。其中的一条语句(SP:StmtCompleted)也就是排在第二位的语句,存储过程的执行时间大部分消耗这条子语句上!

这个例子可以看出业务系统中使用最频繁,且远远高于其他处理的语句就是这个执行3W8Q多次的语句。

   那么看到这样的数据,想做优化当然要从这条语句下手了!它就是你最常开的车了! 这个例子中只要解决了这条语句的性能问题,整个系统性能就可以有一个质的飞跃。

--------------------------------上面的情况,你很专一,只喜欢开一种车!----------------------------

   这个例子中,你喜欢开的车就比较多了,也就是说需要你关注,并且优化的语句较多。(很多语句执行次数都很频繁,也就是系统中使用到的频繁功能较多)

   

   

   系统优化需要循序渐进,从系统最频繁的语句出发,逐个解决语句问题。

   有人看到这会说,博主你有工具,能收集、能统计,我啥也没有咋整?不要急后文脚本都会奉上!

改装前的知识储备

  知识储备很重要,语句的优化涉及的地方很多很多,要么为什么说可以写本书呢?

  1. 你知道什么是执行计划么?如何在语句执行的同时,看到执行计划?
  2. 你知道索引有几种?有什么区别么?
  3. 你知道有索引和没索引,语句执行的区别么?
  4. 你知道什么是统计信息么?
  5. 你知道什么是临时表,表变量,CTE?有什么区别?
  6. 什么是事务?什么是隔离级别?
  7. 你知道什么是逻辑读,什么是物理读,什么是预读么?怎么查看你执行消耗的IO资源?
  8. 你知道什么是等待?怎么查看你运行的语句是否在等待?等待反应出的问题是什么?
  9. 你了解SQL的锁机制么?
  10. 你了解TempDB么?什么样的语句会使用TempDB?
  11. 编译与重编译?
  12. 查询提示是干什么的?
  13. .....
  14. .....
  15. .....
  16. .....

常见的改装方式

------------------------------------新手区-----------高手勿进-------------------------------------  

  是不是就没法短时间内,掌握大部分语句的优化技巧呢? 这是可以的,简单介绍一下语句简单粗暴的调优方式:

  

开启执行计划,让执行计划告诉你,语句慢的原因

  

透过计划,一眼看出索引

   

   当语句执行后,执行计划中会提示你这条运行的语句中是否缺少索引,右键绿色部分"缺少索引提示",点击缺少索引详细信息,生成对应的索引脚本,创在在数据库中。

   在次执行语句验证是否有效,如果还继续提示索引缺失,继续按照此方法创建索引。

   

   索引对于一个语句的影响很大,一个有效的索引可以缩短语句的执行时间,并且降低CPU、IO、内存等消耗。也就是说不但让你的语句执行快,更降低了宝贵的系统资源消耗!

   执行计划中除了可以看出缺失的索引,也可以看出语句的主要消耗在哪。知道了主要消耗,我们也就可以针对这个消耗进行优化。如例子中94%的开销在表的扫描上。当看到这个开销很大并且是一个扫描的时候,第一反应要看扫描的表,有没有筛选条件“where”条件,或 “关联条件join" 如果有条件,那就看为什么没有先用条件过滤数据!是不是没有索引? 是不是创建的索引不能用(隐式转换?列上有函数?等等,具体为什么不能使用索引,请自行百度)

   高能提示:不要小看索引,感觉这都是小儿科。在我亲身经历的众多客户之中,大面积缺少索引的系统可以占到三层以上。或是软件开发完,对数据库就没有建立索引,或是随着系统的日积月累,数据量、功能也随之增加,系统得不到一个及时的跟踪优化导致。

    

降低语句的复杂度

  讲一个我自己的故事,我刚从业的时候对数据库的优化了解不深,一度认为自己写的SQL 好牛逼,因为现在给我,我真是看不懂。一个语句两张A4纸都打印不下!各种子查询,视图嵌套,函数嵌套,UNION ALL等等等。

不能否认这种语句写出来以后,有种小自豪感!因为别人根本看不懂,改也改不了!这种语句在对于SQL 的优化器来说就是灾难,下面简单的说下优化器拿到一条语句怎么样作出执行计划:

  首先传入一个语句,如果有视图,则会把你视图内的代码和外层代码经过二次编译变成一个大语句(多层视图都会编译成一个),然后从表连接开始,优化器会根据统计信息,和一些预查询(如执行所需要的字段类型长度,数据量等)针对你的条件选用一个表作为驱动表,然后继续和其他的表关联,并选用关联方式(hash、merge、nested loop)等,每次关联顺序和方式的都基于SQL的预估,也就是关联的越多,最后的预估可能越不准确,进而导致选用一个比较差的计划。为什么有好的不选却选出一个差的呢?因为优化器不会把你所有执行的可能都验证一次,然后选择一个最好的。这里选出来的“最优”的只是一个相对值。

  介绍的有点跑题了,下面我们说一下降低语句复杂度的常用方式:最常用的就是临时表,比如先把条件筛选性较强的几张表关联,然后把结果放入临时表,在用临时表和其他表关联。可以理解成我有10张表关联,我先拿5张表出来关联,然后把结果放入临时表,再跟另外5张表关联。这样这个查询的复杂度由10张表的联合变成 5+6,这样降低了复杂语句复杂度。

  复杂视图也是如此,在视图和外层关联前,放入临时表,再跟外层关联。

  子查询也是如此,可以分离出来成为临时表的子查询,先分离出来。

  

  情况很多种,最终目的就是降低语句复杂性,让语句分多个步骤执行,这样也可以让优化器每次选出一个比较稳定的计划(一个语句执行有时快有时慢,也很可能是语句的复杂性导致的)。

  

  高能提示:部分系统核心处理的语句比较复杂,且已经很多年前留下的遗产了,经历了一代又一代,我真心不敢碰。那么恭喜你中奖了,好好分析下业务,通过临时表拆分语句还是有可能的!

       临时表和表变量,最大的区别是表变量作为中间过程表不能插入太多数据,如果数据插入的多严重影响性能。

降低并行度,使用并行提升性能

  这个小标题好像有些矛盾!解释一下降低并行度是因为现在的服务器配置CPU数都很大64或更多的随处可见,系统选用并行计划时,使用过多的CPU 反而会使性能下降具体请参见:Expert 诊断优化系列------------------你的CPU高么?

  首先看一个等待: CXPACKET

  

   

   CXPACKET 是最常见的等待之一,等待 并行计划 CPU的调度,或线程上的资源等待,请参见

sys.dm_os_waiting_tasks 引发的疑问(上)

sys.dm_os_waiting_tasks 引发的疑问(中)

sys.dm_os_waiting_tasks 引发的疑问(下)

   当你看见如图的等待情况时,说明你系统中并行度需要调整了!请参见系列中的CPU篇,这里不过多介绍。

   另一种情况,语句可以通过并行来提升执行时间,这里也不过多介绍,请参见SQL提示介绍-强制并行

使用一切方法降低读次数

  一个语句运行起来消耗的读次数也少,说可以间接说明这个语句优化程度较高,读取的页数少也会降低内存和磁盘的压力。

   优化时可以开set statistics io on 来观察语句的IO消耗情况。降低IO的主要方式就是添加索引和降低语句复杂度。

   注:重点关注读次数多的表!

   

   这里就不细说了!

不能忽视的硬件问题

  前三篇一直在强调语句很影响服务器资源。但不能忽略的一点就是,语句的运行好坏也很依赖于资源,硬件资源就好比路面环境。语句这车再好,路没有那么宽,也不平坦,再好的车也跑不起来。

反过来就算硬件足够好,路够宽也够好,没有好车也是跑不起来的!

  

--------------博客地址---------------------------------------------------------------------------------------

Expert 诊断优化系列 http://www.cnblogs.com/double-K/

-----------------------------------------------------------------------------------------------------

  总结:语句运行的效率是系统的关键,而运行最频繁的语句就是关键中的关键。找出系统运行频率高且效率较差的语句进行优化,是优化思路中的核心。

     80%的优化不需要你有高深的技术积累,程咬金的三板斧轮上去,也会扫倒一大片的。请参见 ”常见改装“中的三种手段。

     剩下20%的优化就需要对知识的不断积累,在实际场景中获得更好的知识提升。

     

     硬件和语句相互依赖,都是最优的那自然是好,但是作为技术人员我们保证系统语句是最优的,也是一种责任的体现!

     

     本文只是非常简单的介绍常规优化的思路和方法,不足之处请谅解。后续文章中也会针对等待、执行计划、tempDB等继续细说系统的优化。

   PS: 优化需要使用各种手段,反复尝试才能达到一个最好的效果,优化无止境。

-------------------------干货到了---------------------------------------------------------------------------    

 没有自己的SQL工具怎么找出执行频繁的语句呢?

  1. profiler 对系统进行监控(不会的小伙伴,快去百度吧)  
  2. DMV视图 ,筛选条件请自行修改

with aa as (
SELECT
--执行次数
QS.execution_count,
--查询语句
SUBSTRING(ST.text,(QS.statement_start_offset/2)+1,
((CASE QS.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
ELSE QS.statement_end_offset END - QS.statement_start_offset)/2) + 1
) AS statement_text,
--执行文本
ST.text,
--执行计划
qs.last_elapsed_time,
qs.min_elapsed_time,
qs.max_elapsed_time,
QS.total_worker_time,
QS.last_worker_time,
QS.max_worker_time,
QS.min_worker_time
FROM
sys.dm_exec_query_stats QS
--关键字
CROSS APPLY
sys.dm_exec_sql_text(QS.sql_handle) ST
WHERE
QS.last_execution_time > ‘2016-02-14 00:00:00‘ and  execution_count > 500

-- AND ST.text LIKE ‘%%‘
--ORDER BY
--QS.execution_count DESC

)
select text,max(execution_count) execution_count --,last_elapsed_time,min_elapsed_time,max_elapsed_time
from aa
where [text] not  like ‘%sp_MSupd_%‘ and  [text] not like ‘%sp_MSins_%‘ and  [text] not like ‘%sp_MSdel_%‘
group by text
order by 2  desc

 怎么查看自己系统缺失的索引?适合大批量创建索引

这里的DMV信息只是记录自上次SQL Server启动以后的信息项,也就是说每次重启之后这部分信息就丢失了,所以对于生产系统,建议确保运行了一段周期之后再进行查看。

在我们重新创建聚集索引的时候,SQL Server会默认的重新生成全部非聚集索引,如果表数据量特别大,这个过程会很漫长,如果不指定ONLINE的话,这个过程会是锁定索引B-Teee的,这就意味着是阻塞的,业务就要停下来等待完成操作。

------------------缺失索引-----------------------
SELECT migs.group_handle, mid.*
FROM sys.dm_db_missing_index_group_stats AS migs
INNER JOIN sys.dm_db_missing_index_groups AS mig
ON (migs.group_handle = mig.index_group_handle)
INNER JOIN sys.dm_db_missing_index_details AS mid
ON (mig.index_handle = mid.index_handle)
WHERE migs.group_handle = 2
----------------------------------无用索引----------------------
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT
DB_NAME() AS DatbaseName
, SCHEMA_NAME(O.Schema_ID) AS SchemaName
, OBJECT_NAME(I.object_id) AS TableName
, I.name AS IndexName
INTO #TempNeverUsedIndexes
FROM sys.indexes I INNER JOIN sys.objects O ON I.object_id = O.object_id
WHERE 1=2
EXEC sp_MSForEachDB ‘USE [?]; INSERT INTO #TempNeverUsedIndexes
SELECT
DB_NAME() AS DatbaseName
, SCHEMA_NAME(O.Schema_ID) AS SchemaName
, OBJECT_NAME(I.object_id) AS TableName
, I.NAME AS IndexName
FROM sys.indexes I INNER JOIN sys.objects O ON I.object_id = O.object_id
LEFT OUTER JOIN sys.dm_db_index_usage_stats S ON S.object_id = I.object_id
AND I.index_id = S.index_id
AND DATABASE_ID = DB_ID()
WHERE OBJECTPROPERTY(O.object_id,‘‘IsMsShipped‘‘) = 0
AND I.name IS NOT NULL
AND S.object_id IS NULL‘
SELECT * FROM #TempNeverUsedIndexes
ORDER BY DatbaseName, SchemaName, TableName, IndexName
DROP TABLE #TempNeverUsedIndexes

--------------------------经常被大量更新,但是却基本不适用的索引项--------------------
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT
DB_NAME() AS DatabaseName
, SCHEMA_NAME(o.Schema_ID) AS SchemaName
, OBJECT_NAME(s.[object_id]) AS TableName
, i.name AS IndexName
, s.user_updates
, s.system_seeks + s.system_scans + s.system_lookups
AS [System usage]
INTO #TempUnusedIndexes
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
INNER JOIN sys.objects o ON i.object_id = O.object_id
WHERE 1=2
EXEC sp_MSForEachDB ‘USE [?]; INSERT INTO #TempUnusedIndexes
SELECT TOP 20
DB_NAME() AS DatabaseName
, SCHEMA_NAME(o.Schema_ID) AS SchemaName
, OBJECT_NAME(s.[object_id]) AS TableName
, i.name AS IndexName
, s.user_updates
, s.system_seeks + s.system_scans + s.system_lookups
AS [System usage]
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
INNER JOIN sys.objects o ON i.object_id = O.object_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], ‘‘IsMsShipped‘‘) = 0
AND s.user_seeks = 0
AND s.user_scans = 0
AND s.user_lookups = 0
AND i.name IS NOT NULL
ORDER BY s.user_updates DESC‘
SELECT TOP 20 * FROM #TempUnusedIndexes ORDER BY [user_updates] DESC
DROP TABLE #TempUnusedIndexes

----------------------------------------------------------------------------------------------------

注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,非常感谢!

  引用高大侠的一句话 :“拒绝SQL Server背锅,从我做起!”

为了方便阅读给出系列文章的导读链接:

SQL SERVER全面优化-------Expert for SQL Server 诊断系列

原文地址:https://www.cnblogs.com/Alex80/p/9716042.html

时间: 2024-10-08 14:50:21

SQL语句调优三板斧的相关文章

mysql数据库sql语句调优 、

mysql数据库sql语句调优 . 索引设计原则: 索引列一般为where子句中的列或连接字句中的列 尽量不对基数小的列做索引,如性别列 尽可能使用短索引:如果对字符列索引尽量指定最小长度. (short Keys are better,Integer best) create index cityname on city(city(10)); 复合索引前缀特性,索引的顺序很重要. key(a,b,c)联合索引: 可以走索引的组合:key(a),key(a,b ),key(a,b,c) 下列索引

MySQL千万级多表关联SQL语句调优

本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化,使千万级表关联查询第一页结果能在2秒内完成(真实业务告警系统优化结果). 需要优化的查询:使用explain 出现了Using temporary: 有分页时出现了Using filesort则表示使用不了索引,需要根据下面的技巧来调整语句 rows过多,或者几乎是全表的记录数: key 是 (NULL): possible_keys 出现过多(待选)索引. 1.使用explain语法,对SQL进行

SQL语句调优

sql语句优化原则 性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句,要设法对之进行简化. 常见的简化规则如下: 1)不要有超过5个以上的表连接(JOIN)2)考虑使用临时表或表变量存放中间结果.3)少用子查询4)视图嵌套不要过深,一般视图嵌套不要超过2个为宜. 连接的表越多,其编译的时间和连接的开销也越大,性能越不好控制. 最好是把连接拆开成较小的几

SQL 语句调优 where 条件 数据类型 临时表 索引

基本原则 避免全表扫描 建立索引 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理 尽量避免大事务操作,提高系统并发能力 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效.尽量避免使用游标,因为游标的效率较差. where 后的条件 应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描. 应尽量避免在 where 子句中使用 or 来连接条件,可以考虑使用union 代替 in 和

SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲言少叙,进入本篇的内容. 技术准备 数据库版本为SQL Server2012,利用微软的以前的案例库(Northwind)进行分析,部分内容也会应用微软的另一个案例库AdventureWorks. 相信了解SQL Server的朋友,对这两个库都不会太陌生. 一.并行Hint提示 (MAXDOP N

SQL Server调优系列玩转篇二(如何利用汇聚联合提示(Hint)引导语句运行)

原文:SQL Server调优系列玩转篇二(如何利用汇聚联合提示(Hint)引导语句运行) 前言 上一篇我们分析了查询Hint的用法,作为调优系列的最后一个玩转模块的第一篇.有兴趣的可以点击查看:SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行) 本篇继续玩转模块的内容,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲言少叙,进入本篇的内容. 技术准备 数据库版本为SQL Server2012,利用微软的以前的案例库(Northwind)进行分析,

SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)

前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分6篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划.掌握执行计划优化点,并一一列举了日常我们平常所写的T-SQL语句所会应用的运算符.我相信你平常所写的T-SQL语句在这几篇文章中都能找到相应的分解运算符. 第二个模块注重SQL Server执行T-SQL语句的时候一些内幕解析,共分为5篇文章完成,其中包括:查询优化器的运行方式.运行时几个优化指标值

SQL Server调优系列进阶篇(查询语句运行几个指标值监测)

原文:SQL Server调优系列进阶篇(查询语句运行几个指标值监测) 前言 上一篇我们分析了查询优化器的工作方式,其中包括:查询优化器的详细运行步骤.筛选条件分析.索引项优化等信息. 本篇我们分析在我们运行的过程中几个关键指标值的检测. 通过这些指标值来分析语句的运行问题,并且分析其优化方式. 通过本篇我们可以学习到调优中经常利用的几个利器! 废话少说,开始本篇的正题. 技术准备 数据库版本为SQL Server2008R2,利用微软的一个更简洁的案例库(Northwind)进行分析. 利器一

SQL Server调优系列基础篇(联合运算符总结)

前言 上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧. 废话少说,直接进入本篇的主题. 技术准备 基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析. 一.联合运算符 所谓的联合运算符,其实应用最多的就两种:UNION ALL和UNION. 这两个运算符用法很简单,前者是将两个数据集结果合并,后者则是合并后进行去重操作,如果有过写T-SQL语句的码农都不会陌生. 我们来分析下