SQL Server调优系列进阶篇(如何索引调优)

前言

上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布。不清楚的童鞋可以点击参考。

作为调优系列的文章,数据库的索引肯定是不能少的了,所以本篇我们就开始分析这块内容,关于索引的基础知识就不打算深入分析了,网上一搜一片片的,本篇更侧重的是一些实战项内容展示,希望通过本篇文章各位看官能在真正的场景中找到合适的解决方法足以。

对于索引的使用,我希望的是遇到问题找到合适的解决方法就可以,切勿乱用!!!

本篇在分析出索引的优越性的同时也将负面影响展现出来。

技术准备

数据库版本为SQL Server2012,前几篇文章用的是SQL Server2008RT,内容区别不大,利用微软的以前的案例库(Northwind)进行分析,部分内容也会应用微软的另一个案例库AdventureWorks

相信了解SQL Server的朋友,对这两个库都不会太陌生。

概念理解

所谓的索引同SQL Server中的其它类型的数据页一样,也是固定的8KB(8192字节),存储方式同为B-Tree结构,索引B树中的每一页称为一个索引节点。B树顶端节点为根节点。索引中的底层节点称为叶节点。根节点与叶节点之间的任何索引统称为中间级。

算了,描述起来太麻烦,联机丛书上截个图直观的展示结构:

Continue reading “SQL Server调优系列进阶篇(如何索引调优)”

SQL Server调优系列进阶篇(深入剖析统计信息)

前言

经过前几篇的分析,其实大体已经初窥到SQL Server统计信息的重要性了,所以本篇就要祭出这个神器了。

该篇内容会很长,坐好板凳,瓜子零食之类…

不废话,进正题

技术准备

数据库版本为SQL Server2008R2,利用微软的以前的案例库(Northwind)进行分析,部分内容也会应用微软的另一个案例库AdventureWorks

相信了解SQL Server的朋友,对这两个库都不会太陌生。

概念理解

关于SQL Server中的统计信息,在联机丛书中是这样解释的

查询优化的统计信息是一些对象,这些对象包含与值在表或索引视图的一列或多列中的分布有关的统计信息。查询优化器使用这些统计信息来估计查询结果中的基数或行数。通过这些基数估计,查询优化器可以创建高质量的查询计划。例如,查询优化器可以使用基数估计选择索引查找运算符而不是耗费更多资源的索引扫描运算符,从而提高查询性能。

其实关于统计信息的作用通俗点将就是:SQL Server通过统计信息理解库中每张表的数据内容项分布,知道里面数据“长得啥德行,做到心中有数”,这样每次查询语句的时候就可以根据表中的数据分布,基本能定位到要查找数据的内容位置。

比如,我记得我以前有篇文章写过一个相同的查询语句,但是产生了完全不同的查询计划,这里回顾下,基本如下:

SELECT * FROM Person.Contact
WHERE FirstName LIKE 'K%'

SELECT * FROM Person.Contact
WHERE FirstName LIKE 'Y%'

完全相同的查询语句,只是查询条件不同,一个查找以K开头的顾客,一个查找以Y开头的顾客,却产生了完全不同的查询计划。

其实,这里的原因就是统计信息在作祟。 Continue reading “SQL Server调优系列进阶篇(深入剖析统计信息)”

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

前言

上一篇我们分析了查询优化器的工作方式,其中包括:查询优化器的详细运行步骤、筛选条件分析、索引项优化等信息。

本篇我们分析在我们运行的过程中几个关键指标值的检测。

通过这些指标值来分析语句的运行问题,并且分析其优化方式。

通过本篇我们可以学习到调优中经常利用的几个利器!

废话少说,开始本篇的正题。

技术准备

数据库版本为SQL Server2008R2,利用微软的一个更简洁的案例库(Northwind)进行分析。

利器一、IO统计

通过这个IO统计能为我们分析出当前查询语句所要扫描的数据页的数量。这里面有几个重要的概念,我们依次分析。

方法很简单,一行代码搞定:

SET STATISTICS IO ON

来看个例子

SET STATISTICS IO ON
GO
SELECT * FROM Person.Contact

这里可以看到这个语句对于数据表的操作次数,基于数据页的扫描项。 Continue reading “SQL Server调优系列进阶篇(查询语句运行几个指标值监测)”

SQL Server调优系列进阶篇(查询优化器的运行方式)

前言

前面我们的几篇文章介绍了一系列关于运算符的基础介绍,以及各个运算符的优化方式和技巧。其中涵盖:查看执行计划的方式、几种数据集常用的连接方式、联合运算符方式、并行运算符等一系列的我们常见的运算符。有兴趣的童鞋可以点击查看。

本篇介绍在SQL Server中查询优化器的工作方式,也就是一个好的执行计划的形成,是如何评估出来的,作为该系列的进阶篇。

废话少说,开始本篇的正题。

技术准备

数据库版本为SQL Server2008R2,利用微软的一个更简洁的案例库(Northwind)进行分析。

正文内容

在我们将写好的一个T-SQL语句抛给SQL Server准备执行的时候,首选要经历的过程就是编译过程,当然如果此语句以前在SQL Server中执行过,那么将检测是否存在已经缓存的编译过的执行计划,用以重用。

但是,执行编译的过程需要执行一系列的优化过程,关于优化过程大致分为两个阶段:

1、首先,SQL Server对我们写的T-SQL语句先执行一些简化,通常由查询本身来寻找交互性及重新安排操作的顺序。

在此过程中,SQL Server侧重于语句写法调整,而不过多的考虑成本或者分析索引可用性的等,最重要的目标就是产生一个有效的查询。

然后,SQL Server才会加载元数据,包括索引的统计信息,进入第二个阶段。

2、在这个阶段才是SQL Server一个复杂的优化过程,这个阶段SQL Server会根据上一阶段形成的执行计划运算符进行评估和尝试,甚至于重组执行计划,所以相对这个优化过程是一个耗时的过程。

通过如下流程图,来理解该过程:

Continue reading “SQL Server调优系列进阶篇(查询优化器的运行方式)”

SQL Server调优系列基础篇(子查询运算总结)

前言

前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧。其中涵盖:查看执行计划的方式、几种数据集常用的连接方式、联合运算符方式、并行运算符等一系列的我们常见的运算符。有兴趣的童鞋可以点击查看。

本篇我们介绍关于子查询语句的一系列内容,子查询一般是我们形成复杂查询的一些基础性操作,所以关于子查询的应用方式就非常重要。

废话少说,开始本篇的正题。

技术准备

数据库版本为SQL Server2008R2,利用微软的一个更简洁的案例库(Northwind)进行分析。

一、独立的子查询方式

所谓的独立的子查询方式,就是说子查询和主查询没有相关性,这样带来的好处就是子查询不依赖于外部查询,所以可以独立外部查询而被评估,形成自己的执行计划执行。

举个例子

SELECT O1.OrderID,O1.Freight
FROM Orders O1
WHERE O1.Freight>
(
   SELECT AVG(O2.Freight)
   FROM Orders O2
)

这句SQL执行的目标是查询订单中运费大于平均运费数的订单。

这里提取平均运费的子句就是一个完全独立的子查询,完全不依赖主查询而独立执行。同时这里我们这里利用利用一个标量计算(AVG),因此正好返回一行。

查看一下该语句的查询计划:

这个查询计划没啥好介绍的,关于子查询的执行计划形成可以参照我的第二篇:SQL Server调优系列基础篇(常用运算符总结) Continue reading “SQL Server调优系列基础篇(子查询运算总结)”

SQL Server调优系列基础篇(索引运算总结)

前言

上几篇文章我们介绍了如何查看查询计划、常用运算符的介绍、并行运算的方式,有兴趣的可以点击查看。

本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方式可以指导我们如何建立索引、调整我们的查询语句,达到性能优化的目的。

闲言少叙,进入本篇的正题。

技术准备

基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析。

简介

所谓的索引应用就是在我们日常写的T-SQL语句中,如何利用现有的索引项,再分析的话就是我们所写的查询条件,其实大部分情况也无非以下几种:

1、等于谓词:select …where…[email protected]

2、比较谓词:select …where…column> or < or  <> or <= or >= @parameter

3、范围谓词:select …where…column in or not in  or between and @parameter

4、逻辑谓词:select …where…一个谓词 or、and 其它谓词 or、and 更多谓词….

我们就依次分析上面几种情况下,如何利用索引进行查询优化的

一、动态索引查找

所谓的动态索引查找就是SQL Server在执行语句的时候,才格式化查询条件,然后根据查询条件的不同自动的去匹配索引项,达到性能提升的目的。

来举个例子

SET SHOWPLAN_TEXT ON
GO
SELECT OrderID
FROM Orders
WHERE ShipPostalCode IN (N'05022',N'99362')

Continue reading “SQL Server调优系列基础篇(索引运算总结)”

SQL Server调优系列基础篇(并行运算总结篇二)

前言

上一篇文章我们介绍了查看查询计划的并行运行方式。

本篇我们接着分析SQL Server的并行运算。

闲言少叙,直接进入本篇的正题。

技术准备

同前几篇一样,基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析。

内容

文章开始前,我们先来回顾上一篇中介绍的并行运算,来看文章最后介绍的并行运算语句:

SELECT B1.[KEY],B1.DATA,B2.DATA 
FROM BigTable B1 JOIN BigTable2 B2
ON B1.[KEY]=B2.[KEY]
WHERE B1.DATA<100

上面是详细的执行计划,从右边依次向左执行,上图中有一个地方很有意思,就是在聚集索引扫描后获取的数据,又重新了使用了一次重新分配任务的过程(Repartition Streams),就是上图的将获取的100行数据重新分配到并行的各个线程中。 Continue reading “SQL Server调优系列基础篇(并行运算总结篇二)”

SQL Server调优系列基础篇(并行运算总结一)

前言

上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符、联合运算符的优化技巧。

本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自己的查询计划,来适应硬件资源的扩展,充分利用硬件资源,最大限度的提高性能。

闲言少叙,直接进入本篇的正题。

技术准备

同前几篇一样,基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析。

一、并行运算符

在我们日常所写的T-SQL语句,并不是所有的最优执行计划都是一样的,其最优的执行计划的形成需要多方面的评估才可以,大部分根据SQL Server本身所形成的统计信息,然后对形成的多个执行计划进行评估,进而选出最优的执行方式。

在SQL Server根据库内容形成的统计信息进行评估的同时,还要参照当前运行的硬件资源,有时候它认为最优的方案可能当前硬件资源不支持,比如:内存限制、CPU限制、IO瓶颈等,所以执行计划的优劣还要依赖于底层硬件。

当SQL Server发现某个处理的数据集比较大,耗费资源比较多时,但此时硬件存在多颗CPU时,SQL Server会尝试使用并行的方法,把数据集拆分成若干个,若干个线程同时处理,来提高整体效率。

在SQL Server中可以通过如下方法,设置SQL Server可用的CPU个数

默认SQL Server会自动选择CPU个数,当然不排除某些情况下,比如高并发的生产环境中,防止SQL Server独占所有CPU,所以提供了该配置的界面。 Continue reading “SQL Server调优系列基础篇(并行运算总结一)”

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

前言

上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧。

废话少说,直接进入本篇的主题。

技术准备

基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析。

一、联合运算符

所谓的联合运算符,其实应用最多的就两种:UNION ALL和UNION。

这两个运算符用法很简单,前者是将两个数据集结果合并,后者则是合并后进行去重操作,如果有过写T-SQL语句的码农都不会陌生。

我们来分析下这两个运算符在执行计划中的显示,举个例子

SELECT FirstName+N''+LastName,City,Country FROM Employees
UNION ALL
SELECT ContactName,City,Country FROM Customers

就是上面这个图标了,这就是UNION ALL联合运算符的图标。

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

SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)

前言

上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握。

通过本篇可以了解我们平常所写的T-SQL语句,在SQL Server数据库系统中是如何分解执行的,数据结果如何通过各个运算符组织形成的。

技术准备

基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析。

一、数据连接

数据连接是我们在写T-SQL语句的时候最常用的,通过两个表之间关联获取想要的数据。

SQL Server默认支持三种物理连接运算符:嵌套循环连接、合并连接以及哈希连接。三种连接各有用途,各有特点,不同的场景会数据库会为我们选择最优的连接方式。

a、嵌套循环连接(nested loops join)

嵌套循环连接是最简单也是最基础的连接方式。两张表通过关键字进行关联,然后通过双层循环依次进行两张表的行进行关联,然后通过关键字进行筛选。

可以参照下图进行理解分析

其实嵌套扫描是很简单的获取数据的方式,简单点就是两层循环过滤出结果值。

我们可以通过如下代码加深理解

for each row R1 in the outer table
   for each row R2 int the inner table
       if R1 join with R2
       return (R1,R2)

举个列子 Continue reading “SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)”