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

    当优化器所选择的非聚簇索引只包含查询请求的一部分字段时,就需要一个查找(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

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

  1. mysql经纬度查询并且计算2KM范围内附近用户的sql查询性能优化实例教程

    之前很傻很天真地以为无非就是逐个计算距离,然后比较出来就行了,然后当碰到访问用户很多,而且数据库中经纬度信息很多的时候,计算量的迅速增长,能让服务器完全傻逼掉,还是老前辈的经验比我们丰富,给了我很大的 ...

  2. SQL查询性能优化

    使用高效的查询 使用 EXISTS 代替 IN -- 查询A表中同时存在B表的数据 -- 慢 SELECT * FROM Class_A WHERE id IN (SELECT id FROM Cla ...

  3. Mysql sql查询性能侦查

    Mysql 服务性能优化配置:http://5434718.blog.51cto.com/5424718/1207526[该文章很好] Sql查询性能优化 对Sql进行优化,肯定是该Sql运行未能达到 ...

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

    小小程序猿SQL Server认知的成长 1.没毕业或工作没多久,只知道有数据库.SQL这么个东东,浑然分不清SQL和Sql Server Oracle.MySql的关系,通常认为SQL就是SQL S ...

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

    据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是, ...

  6. SQl语句查询性能优化

    [摘要]本文从DBMS的查询优化器对SQL查询语句进行性能优化的角度出发,结合数据库理论,从查询表达式及其多种查询条件组合对数据库查询性能优化进行分析,总结出多种提高数据库查询性能优化策略,介绍索引的 ...

  7. SQL SERVER 查询性能优化——分析事务与锁(五)

    SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...

  8. SQL Server 查询性能优化 相关文章

    来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Ser ...

  9. SQL Server查询性能优化——覆盖索引(二)

    在SQL Server 查询性能优化——覆盖索引(一)中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索引等 ...

随机推荐

  1. SQL存储过程解密

    首先要建立一张表和一个存储过程: SQL_DECODE表: CREATE TABLE [dbo].[SQL_DECODE]( ,) NOT NULL, [SQLTEXT] [nvarchar](max ...

  2. git&sourcetree安装及在IntelliIJ下拉取项目基础使用

    be careful: 1)git版本与Sourcetree版本最好一致 ,不能git为2.5,sourcetree为1.8 2)先安装git再安装Sourcetree 3)拥有git和sourcet ...

  3. C#多文档程序中如何只打开一个子窗口

    using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; na ...

  4. jQuery validate兼容IE8写法

    最近做项目的时候遇到一个validate插件在IE8下面点击submit按钮没有执行检查的BUG 在chrome和FF,还有IE9以上都可以.百度了好多文章都没有找到解决方法,后面自己测试找到了问题. ...

  5. 20个编写现代CSS代码的建议

    明白何谓Margin Collapse 不同于其他很多属性,盒模型中垂直方向上的Margin会在相遇时发生崩塌,也就是说当某个元素的底部Margin与另一个元素的顶部Margin相邻时,只有二者中的较 ...

  6. dump 分析模式之 INCORRECT STACK TRACE - djm2005dy的专栏 - 博客频道 - CSDN.NET

    Dump 分析模式之 INCORRECT STACK TRACE dump 分析模式之 INCORRECT STACK TRACE 翻译自 MDA-Anthology Page288  初学者常犯的错 ...

  7. adb常用命令

    adb命令的主要用途  1. 运行android设备的shell(命令行).  2.管理模拟器或android设备的映射端口.  3. 安装和卸载应用程序.  4.计算机和android设备之间的上传 ...

  8. 通过innobackupex实现对MySQL的增量备份与还原

    备份 增量备份是基于完整备份的,所以我们需要先做一次完整备份: innobackupex --password=test /backup/ 备注:test是我的MySQL服务的root用户的密码,/b ...

  9. DNS服务器原理

    19.1 什么是DNS   主机名自动解析为 IP 就很重要!那就是 DNS.   19.1.1 用网络主机名取得IP的历史渊源   单一档案处理上网的年代: /etc/hosts   利用某些特定的 ...

  10. XML.01-语法简介

    body,td { font-family: calibri; font-size: 10pt }   XML.01-语法简介 文档声明 元素(标签) 属性 注释 特殊字符 CDATA区域 处理指令 ...