zoukankan      html  css  js  c++  java
  • SQL Server 查询性能优化——索引与SARG(二)

     

    接 SQL Server 查询性能优化——索引与SARG(一)

    对于非SARG语句,SQL SERVER 必须评估每一条记录以决定它是否符合WHERE子句的条件。所以索引对于采用非SARG条件的查询通常没什么用处。而通过非SARG语句通常包含以下操作: NOT、!=、<>、!>、!< 、NOT EXISTS 、NOT IN 和NOT LIKE 等,以及上述提及的“%IS%”,其中LIKE使用方法会造成全表扫描(TARLE SCAN)或是聚集扫描而降低性能.

    创建SQL Server 查询性能优化——索引与SARG(一)中开头部分创建索引中的索引1,3

    --例一、
    
    SELECT *  FROM [WBK_PDE_LIST_ORG_HISTROY] where COP_G_NO like '%79'
    

    'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1306 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

     

     

     

    --例二、
    
      SELECT *  FROM [WBK_PDE_LIST_ORG_HISTROY] with(index(idx_wbk_pde_list_cop_g_no))where COP_G_NO like '0016%'
    
     
    

     

    'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取925 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

     

     

     

    -----例三、
    SELECT *  FROM [WBK_PDE_LIST_ORG_HISTROY]  where COP_G_NO like '0016%'
    

    'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1306 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

     

     

    使用索引

    查询语句

    查询记录数量

    执行成本

    全表扫描

    例一

    916

    1.03687

    指定使用非聚集索引

    例二

    919

    2.24756

    使用聚集索引

    例三

    919

    1.03687

           
           

    从上表中的例一、例三中可以看出全表扫描与聚集索引扫描的执行成本是一样的,或相差不大。而例二中,使用了指定的非聚集索引,由于使用非聚集索引查找 数据,会有一个RID键值查找(或称Bookup Lookup)随机操作,所以当查询的记录数量越多,则执行成本就越大。

     

     

    下面来讲讲一些常见的WHERE子句用法使用不当的情景,并探讨较正确的用法:

    。对WHERE子句做运算。
    。负向查询。
    。对WHERE子句使用函数。
    。使用OR 操作。


    一、 不要对WHERE子句做运算
    先以简单的范例来比较SARG 和非SARG ,你可以通过Managemenet studio来查看查询优化程序是否可以有效分析该语句。

      1 、没有任何索引

     

    ---例一:在WHERE中做运算
    SELECT  *  FROM [WBK_PDE_LIST_ORG_HISTROY] where wbook_no+G_NO='BE40494245002011844'
    
    ---例二:在WHERE中不做运算
    SELECT * FROM [WBK_PDE_LIST_ORG_HISTROY] where wbook_no='BE404942450020' and g_no='11844'

       1) 例一与例二查询的IO读写数

      表'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1306 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

       2)例一与例二的查询执行计划成本

     

     

     

     2、只创建聚集索引。

    ALTER TABLE [dbo].[WBK_PDE_LIST_ORG_HISTROY] ADD  CONSTRAINT [PK_WBK_PDE_LIST_ORG_HISTROY] PRIMARY KEY CLUSTERED 
    
    (
    
    [WBOOK_NO] ASC,
    
    [G_NO] ASC
    
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    
    GO
    

       1) 例一与例二查询的IO读写数

        表'WBK_PDE_LIST_ORG_HISTROY'。扫描计数1,逻辑读取1314 次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

     

       2)例一与例二的查询执行计划成本

     

     

     3  创建SQL Server 查询性能优化——索引与SARG(一)中开头部分创建索引中的索引1(聚集索引)和索引5(非聚集索引)

     

     

       1) 例一的情况同上面2.

       2) 例二查询的IO读写数

    'WBK_PDE_LIST_ORG_HISTROY'。扫描计数0,逻辑读取次,物理读取次,预读次,lob 逻辑读取次,lob 物理读取次,lob 预读次。

       3)例二的查询执行计划成本

     

    从三个执行计划中,可以看到明显的差异。

    因为SARG 的写法让查询优化程序可以直接对比条件常量,可以有效地利用在WHERE子句中的列名字段上建立的聚集索引或非聚集索引。而非SARG 则因为需要运算才知道数据是否符合,导致无法直接使用索引,因而采用聚集索引扫描方式、全表扫描方式、索引扫描方式。

    对于第一个查询语句,由于不符合SARG格式,所以你可以看到查询优化查询并没有有效的利用索引。

     

    第一种情况,查询优化查询对于例一与例二都使用了全表扫描方式,从上图中可以看出整个数据表有共有1306页,

    而此查询语句的逻辑读是1306次,与总数据页差不多,对整个表进行了扫描。与查询计划示意图中所示一样。

    第二种情况,由于没有了idx_WBK_PDE_LIST_COP_G_NO索引,只有聚集索引PK_WBK_PDE_LIST_ORG_HISTROY。从上图中可以看出PK_WBK_PDE_LIST_ORG_HISTROY的索引页共有1306页,而此查询语句的逻辑读是1314次,与总索引页差不多,也是聚集索引扫描,与查询计划示意图中所示一样。

    对于第三种情况,由于符合SARG 格式,而且WHERE子句后面的条件中的字段中都建立有索引,所以你可以看到查询优化程序会有效地利用先前建立的聚集索引(索引1)进行聚集索引查找。速度非常快。

  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/chillsrc/p/2756141.html
Copyright © 2011-2022 走看看