SQL 查询性能优化 解决书签查找_MsSql

先来看看什么是书签查找:

    当优化器所选择的非聚簇索引只包含查询请求的一部分字段时,就需要一个查找(lookup)来检索其他字段来满足请求。对一个有聚簇索引的表来说是一个键查找(key lookup),对一个堆表来说是一个RID查找(RID lookup)。这种查找即是——书签查找。

   书签查找根据索引的行定位器从表中读取数据。因此,除了索引页面的逻辑读取外,还需要数据页面的逻辑读取。

从索引的行定位器到从表中读取数据这之间会产生一些额外的开销,本文就来解决这个开销。

先看下我的测试表结构:

其中可以看出 有一个 聚簇索引 PK_UserID 和一个 非聚簇索引IX_UserName。

看看产生书签 查找的效果:

select UserName,Gender from dbo.UserInfo where UserName='userN600'

按上面的 SQL 产生执行计划 可以看出, 会产生一个书签查找(Key Lookup),如下图

如果把上面的 SQL 改写成

select UserName from dbo.UserInfo where UserName='userN600'


可以看出 书签查找 没有了。

本SQL 产生书签查找的 主要原因是 本SQL 优化器会选择 非聚簇索引IX_UserName,来执生SQL 。IX_UserName 索引不包含 Gender 这个字段 于是产生个从索引到 数据表的 一个 查找 即 书签查找。
解决书签查找:

方法一、使用一个 聚簇索引

    对于聚簇索引, 索引的叶子页面和表的数据页面相同,因此,当读取聚簇索引 键列的值时,数据引擎可以读取其它列的值而不需要任何行定位,这样就解决了书签查找。
     对于这句SQL ( select UserName,Gender from dbo.UserInfo where UserName='userN600')解决了书签查找的办法就是在UserName 上 建聚簇索引 ,因为一个表只有一个聚簇索引 ,这就意味着删除现有聚簇索引(PK_UserID),将会造成其它从表 中的外键约束 要发生更改,这需要考一些相关的工作,可能严重影响依赖于现有聚簇索引的其它查询。

方法二、使用一个 覆盖索引

    覆盖索引 是在所有为满足SQL 查询不用到达基本表所需的列 建立的非聚簇索引。如果查询遇到一个索引并且完全不需要引用底层数据表,那么 该索引可以被认为是 覆盖索引。
      对于这句SQL ( select UserName,Gender from dbo.UserInfo where UserName='userN600') 解决书签查找的办法就是 在非聚簇索引IX_UserName 里包含 Gender 字段。
      也就是在 建索引时 用INCLUDE 语句,具体操作如下

用INCLUDE 最好在 以下情况下使用:
        1、不希望增加索引键的大小,但是仍然可以建一个 覆盖索引;
        2、打算索引一种不能被索引的数据类型(除了文本、NTEXT和图像);
        3、已经超过了一个索引的关键字列的最大数量

方法三、使用 索引连接

  索引连接 是使用多个索引之间一个索引交叉来完全覆盖一个查询。如果覆盖索引变的非常宽,那么就可以考虑索引连接。
    对于这句SQL ( select UserName,Gender from dbo.UserInfo where UserName='userN600' and Gender=1)可以在 Gender 上 建一个非聚簇索引就行了。
    对于这个例 子,可能 SQL 优化器并没有同时 选 用非聚簇索引IX_UserName 和 我们新建立在Gender 上的索引,这时我们可以告知 SQL 优化器 同时使用 这个两上索引,操作如下
      select Gender,UserName from UserInfo with(index (IX_Gender,IX_UserName)) where UserName='jins' and Gender=0

好了就写这么多吧.

时间: 2024-08-03 09:10:12

SQL 查询性能优化 解决书签查找_MsSql的相关文章

SQL语句性能优化(续)_MsSql

上篇介绍了一下自己在项目中遇到的一种使用sql语句的优化方式(性能优化--SQL语句),但是说的不够完整.在对比的过程中,没有将max函数考虑在内,经人提醒之后赶紧做了一个测试,测试过程中又学到了不少的东西. 上次用的是select count(*) 和select * 的执行效率问题,因为我的需求是获取数据的一个总数来自动给出新的id,然后网友给出可以使用max的方式给出新id.其实这也是一种不错的思路(当时我们也用过该函数,只不过因为系统数据本身问题,不适合用该函数),然后我就对max函数的

谈谈Tempdb对SQL Server性能优化有何影响_MsSql

先给大家巩固tempdb的基础知识 简介: tempdb是SQLServer的系统数据库一直都是SQLServer的重要组成部分,用来存储临时对象.可以简单理解tempdb是SQLServer的速写板.应用程序与数据库都可以使用tempdb作为临时的数据存储区.一个实例的所有用户都共享一个Tempdb.很明显,这样的设计不是很好.当多个应用程序的数据库部署在同一台服务器上的时候,应用程序共享tempdb,如果开发人员不注意对Tempdb的使用就会造成这些数据库相互影响从而影响应用程序. 特性:

Sql Server查询性能优化之不可小觑的书签查找介绍_MsSql

小小程序猿SQL Server认知的成长 1.没毕业或工作没多久,只知道有数据库.SQL这么个东东,浑然分不清SQL和Sql Server Oracle.MySql的关系,通常认为SQL就是SQL Server 2.工作好几年了,也写过不少SQL,却浑然不知道索引为何物,只知道数据库有索引这么个东西,分不清聚集索引和非聚集索引,只知道查询慢了建个索引查询就快了,到头来索引也建了不少,查询也确实快了,偶然问之:汝建之索引为何类型?答曰:... 3.终于受到刺激开始奋发图强,买书,gg查资料终于知道

Sql Server查询性能优化之不可小觑的书签查找介绍

小小程序猿SQL Server认知的成长 1.没毕业或工作没多久,只知道有数据库.SQL这么个东东,浑然分不清SQL和Sql Server Oracle.MySql的关系,通常认为SQL就是SQL Server 2.工作好几年了,也写过不少SQL,却浑然不知道索引为何物,只知道数据库有索引这么个东西,分不清聚集索引和非聚集索引,只知道查询慢了建个索引查询就快了,到头来索引也建了不少,查询也确实快了,偶然问之:汝建之索引为何类型?答曰:... 3.终于受到刺激开始奋发图强,买书,gg查资料终于知道

Sql Server 查询性能优化之走出索引的误区分析_MsSql

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的

SQL Server查询性能优化之创建合理的索引(下)

续上一篇SQLServer查询性能优化之创建合理的索引(上) 数据库索引分为聚集索引和非聚集索引,聚集索引就是物理索引,也就是数据的物理的存储顺序,聚集索引的叶子节点就是数据行本身:非聚集索引是逻辑索引,也可以简单的认为是对聚集索引建立的索引,一般来说聚集索引的键就是非聚集索引的叶子节点(在不使用include时). 关于索引的选择 对于索引类型来说没什么好选的,一般来说聚集索引是必须的(有特殊需要的另说),非聚集索引看实际需要灵活建立.因此对于索引来说主要是决定在那些列上建立索引,尤其是对于聚

分析Sql Server查询性能优化之走出索引的误区

误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的观点是错误的,SQL Server查询优化器是基于开销进行选择的优化器,通过一系列复杂判断来决定是否使用索引.使用什么类型索引.使用那个索引.SQL Server内部维护着索引列上的数据的统计,统计信息会随着索引列内容的变化而变化,索引的有效期完全取决于索引列上的统计信息,随着数据的变化关于索引的检索机制也随之变化.对于查询优化器来说始终保持查询开销最低始终是其的不二选择,如果一个非聚集索引的列上有大量的重复值,

Sql Server 查询性能优化之走出索引的误区分析

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的

SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

原文:SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用 近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬.正是受大神们无私奉献精神的影响,所以小弟也作为回报,分享一下关于SET STATISTICS IO和SET STATISTICS TIME这两条T_SQL命令,在查询优化性能中的作用.       首先我想说明一下这篇文章