zoukankan      html  css  js  c++  java
  • 在sqlserver中,优化器如何利用统计信息来估算返回的行数(三)

    来看看多列过滤是如何估计返回的行数

    use AdventureWorks
    go
    --把毫秒全置为0,便于看到效果
    update dbo.DatabaseLog 
    set PostTime=cast(CONVERT(varchar,PostTime,120) as datetime)
    update statistics DatabaseLog with fullscan
    
    --创建event索引
    create index idx_event on dbo.DatabaseLog(Event) with(online=on)
    1. 看如下的SQL,过滤字段上分别建有索引
    select * from dbo.DatabaseLog 
    where PostTime='2006-04-26 11:44:31.000' 
    and event='CREATE_TABLE'
    OPTION
    (
        QUERYTRACEON 3604,
        QUERYTRACEON 9292,
        QUERYTRACEON 9204
    )

    如下的执行计划:

    image

    idx_postTime 估计返回的行数为56,来自于统计信息的直方图:

    image

    idx_event 估计返回行数为69,也是来自直方图:

    image

    那merge Join预估返回的行数10怎么算出来的?merge join 返回的结果应该是idx_postTime结果集,

    idx_event结果集的交集。databaselog的行数为389行。

    merge join 返回的行数: (56./389)*(69./389)*389=9.933052046574,优化器据此估算merge join

    操作符返回的行数。

    优化器在运行期间,确实是加载了idx_postTime/idx_event上的统计信息,如下图所示:

    image

    同时注意,key_Lookup操作符,预估返回的行数是一行,这个行数是执行一次返回的行数,而这个key_lookup操作执行了56次,所以实际

    返回的行数为56行,预估行数=实际行数,如下图所示:

    image

    2.来看下面SQL返回的行数:

    dbcc FreeProcCache
    select * from dbo.DatabaseLog 
    where PostTime='2006-04-26 11:44:31.000' 
    or event='CREATE_TABLE'
    OPTION
    (
        QUERYTRACEON 3604,
        QUERYTRACEON 9292,
        QUERYTRACEON 9204
    )

    这个是全表扫描,如图所示:

    image

    这个预估的行数:postTime 返回的56+event 返回的69-交集的部分9.933052046574=115.067行,

    其中,扫描全表时也加载了postTime/event上手动新建的统计信息,如图所示:

    image

    总结:对于单独的列上建立的索引,优化器根据每个列上的统计信息来预估返回的行数,无论后续执行时是访问索引还是访问基表获得数据!

  • 相关阅读:
    2021软工-提问回顾与个人总结
    2021软工-调研作业-Notion
    2021年软工-个人阅读作业2
    tester
    tableau学做两个集合的维恩图(文氏图)Venn diagram 二维文氏图
    python学习
    pv操作是否会造成死锁呢?
    提问的正确姿势
    【BUAA OO Unit3】史上最全OpenJML摸索实录
    MVC和三层架构的区别
  • 原文地址:https://www.cnblogs.com/fly_zj/p/3038781.html
Copyright © 2011-2022 走看看