)
《Microsoft Sql server 2008 Internals》索引目录《Microsoft Sql server 2008 Internals》读书笔记--目录索引前几篇主要介绍了查询结构优化中的几个关键概念:统计(Statistics)、基准估计(Cardinality estimation)和成本(costing) ,今天开始真正进入主题今天我们关注的是索引选择■Index Selection索引选择是查询优化最重要的一点索引匹配的基本思路是从Where子句、连接条件、或查询中的其他限定操作符中提取谓词并转换这个操作为能被针对索引的操作。两个基本的操作能被针对索引执行、Seek(对一个单个值或索引键的一个值的范围range)2、Scan the Index(向前或向后)对Seek,初始的操作在B树的根节点开始沿b树向下到一个在索引键上的理想的索引位置。一旦完成查询处理器会遍历所有的行以匹配谓词或者直到范围中的最后一个值被找到。因为B树的页在SQL Server中是链接的使用这个结构查找所有的行成为可能只要中间的树节点被遍历过。查询优化器的一个工作是辨别出哪一个谓词能被应用到索引以尽可能快地返回行。某些谓词能被应用到某个索引某些则不能。 如查询select col1,pkcol from myTable where col12 有一个形式为columnconstant的谓词。如果该列有一个索引则这个模式被匹配为一个Seek操作。生成的备选结果是针对一个非聚集索引执行一个seek返回匹配的行。看一个基本索引的例子Create table IdxTest2010(col2 int,col3 int,col4 int);Create index idex2010 on IdxTest2010(col2,col3);select col2,col3 from IdxTest2010 where col25注意查询优化器也可以针对多列索引应用复合谓词只要这个操作能被转换为开始和结束索引键。因此对于如下语句可以得到相同的seek Plan:能被转化为一个索引操作的谓词也被称作“可参数化的搜索”(sargable或search-Argument-able)谓词,这意味着这种谓词的形式可以被转化为一个索引操作。不能转化的则称为non-sargable谓词,它通常在索引seek后被应用这样查询得以返回符合所有谓词的记录行。有时候让人感到迷惑的就是SQL Server通常在查询树的seek/scan操作中评估non-sargable谓词。这是一个优化进程如果不这样做SQL Server步骤如下1、Seek 操作Seek至索引B树中的一个键2、锁页面(latch the page)3、读取行4、释放页面锁5、返回行到筛选索引6、 筛选评估针对这些行的non-sargable谓词如果通过鉴定传递这些行到父操作。否则转到第二步继续下一个候选行。这个流程比最佳要慢一些因为返回这些行到一个不同的操作符需要加载一个不同的列集和数据到CPU。通过保持逻辑在一个地方整个评估查询的CPU成本下降了。在SQL Server中实际的操作类似如下1、Seek 操作Seek至索引B树中的一个键2、锁页面(latch the page)3、读取行4、应用non-sargable谓词筛选如果行没有通过筛选转到第三步。否则转到第五步。5、释放页面锁6、 返回行这就是所谓的pushing non-sargable谓词(谓词被从一个筛选推进seek/scan。这是一个物理优化但它能展示处理多行的查询内部流程。并不是所有的谓词都能被在seek/scan操作中评估。因为锁操作阻止其他用户甚至查看系统中的一个页这个优化被保留给那些成本低廉的谓词。也就是所谓的non-pushing ,non-sargable谓词例子包括■Predicates on Large Objects(包括varbonary(max),varchar(max),nvarchar(max))■CLR函数■一些T-SQL函数谓词可搜索参数化能力在数据库应用程序设计中是一个非常重要的因素。系统性能很差的一个原因是针对数据库的应用程序被写作这样一种方式即谓词non-sargable。在很多情况下这是可以避免的如果主题能被标识得足够早(按照一个可度量的顺序)修正这个issue有时会增加数据应用程序性能。SQL Server在尽量在一个查询中应用针对可搜索参数化的谓词的索引时考虑多种方案。比如对于AND条件(Where col15 AND col2a AND...),SQL Server会试着这样1、对于一个给定的列表该列表中包含需要相等列、不等列、需要适合查询但不带谓词的列首先试图找到一个精确匹配请求的索引。如果有这样一个索引则使用它。2、尽量找到一个索引集以适合等式条件并为所有这样的索引执行一个内连接。3、如果步骤2不能覆盖所有请求的列考虑在解决方案内连接其他基于列集的索引。4、最后执行一个连接到基表得到任何剩余的列。在所有这些案例中每个解决方案的成本被考虑如果它最确认为最低成本的解决方案则返回访方案。因此一个将其他索引连接在一起的解决方案被使用仅仅因为它被确定比其他基表中的所有行的scan要节约成本。其次算法仅仅在本地查询树上执行。即使查询优化器在此过程中生成了一个特定的替代方案它也不一定就是最后查询计划的一部分。成本被用于判定成本最低的完整计划。因此索引选择是一个启发式是更广泛的用于帮助选择高效查询计划的成本基础设施的一部分。■Filter IndexSQL Server 2008推出一种新的功能即在创建索引时可以带简单的谓词以限制包含在索引中的行集。乍看之下这个内容已经包含在索引视图中功能的一个子集。实际上这个功能存在的意义在于1、索引视图使用和维护时成本高昂。2、匹配索引视图内容的兼容性不是在所有SQL Server 版本中都被支持。 3、大量的不同SQL Server用户使用的场景比视图等内容要复杂得多他们可能还是倾向于使用传统的关联查询场景。筛选索引在Create Index语句中使用where子句。Create table TestFilter1(col1 int ,col2 int ); go set nocount on BEGIN TransAction; Declare i int set i0 while i40000 BEGIN Insert into TestFilter1(col1,col2) values(rand()*1000,rand()*1000); set ii1 END Commit Transaction go Create Index idx2011 on TestFilter1(col2) where col2800此时如果执行以下查询则得到筛选索引的支持select col2 from TestFilter1 where col2800如果执行以下查询则得不到筛选索引的支持select col2 from TestFilter1 where col2799筛选索引未完待续。下文将继续了解筛选索引(Filtered Indexes)邀月注本文版权由邀月和CSDN共同所有转载请注明出处。助人等于自助! 3wlive.cn