• 也谈SQL Server 2008 处理隐式数据类型转换在运行计划中的增强 (续)


    在上一篇文章也谈SQL Server 2008 处理隐式数据类型转换在运行计划中的增强 中,我提到了隐式数据类型转换添加对于数据分布非常不平均的表。评估的数据行数与实际值有非常大出入的问题,进一步測试之后,我发现这种评估不准确性应该确实与推測的一样,它使用了变量的评估方式。通过例如以下測试验证,首先建立数据分布不平均的測试表。

    USE tempdb
    GO
    CREATE TABLE _t(
        c varchar(50)
    );
    CREATE INDEX IX_c ON _t( c );
    GO
    
    -- 添加 10000 条数据
    INSERT _t
    SELECT (9999 + id) FROM(
        SELECT TOP 10000 id = ROW_NUMBER() OVER( ORDER BY GETDATE() )
        FROM sys.all_columns a, sys.all_columns
    )ID
    
    -- 将 100 - 10000 的数据变成同样值
    UPDATE _t SET c = '' WHERE c >= '10100'
    

    然后通过 varhcar和nvarchar值分别測试满足条件1条和满足条件8900条的运行计划预估行数。

    ALTER INDEX IX_c ON _t REBUILD;
    GO
    SET SHOWPLAN_ALL ON
    GO
    SELECT * FROM _t WHERE c = '10005';     -- 实际1条
    GO
    SET SHOWPLAN_ALL OFF;
    GO
    
    ALTER INDEX IX_c ON _t REBUILD;
    GO
    SET SHOWPLAN_ALL ON
    GO
    SELECT * FROM _t WHERE c = N'10005';     -- 实际1条
    GO
    SET SHOWPLAN_ALL OFF;
    GO
    
    ALTER INDEX IX_c ON _t REBUILD;
    GO
    SET SHOWPLAN_ALL ON
    GO
    SELECT * FROM _t WHERE c = '';          -- 实际9900条
    GO
    SET SHOWPLAN_ALL OFF;
    GO
    
    ALTER INDEX IX_c ON _t REBUILD;
    GO
    SET SHOWPLAN_ALL ON
    GO
    SELECT * FROM _t WHERE c = N'';         -- 实际9900条
    GO
    SET SHOWPLAN_ALL OFF;
    GO
    

    得到的查询计划预估行数例如以下图所看到的
    这里写图片描写叙述
    从图中显示的预估数据行数能够看到。对于varchar值(不须要隐匿的数据类型转换),其预估的结果是准确的。但对于nvarchar值,无论指定的值是仅仅有一条数据,还是有8900条数据匹配。其预估的结果都是99.0099,这说明预估并没有考虑我们指定的值。
    进一步用变量測试

    ALTER INDEX IX_c ON _t REBUILD;
    GO
    SET SHOWPLAN_ALL ON
    GO
    DECLARE @v varchar;SELECT * FROM _t WHERE c = @v; -- varchar
    GO
    SET SHOWPLAN_ALL OFF;
    GO
    
    ALTER INDEX IX_c ON _t REBUILD;
    GO
    SET SHOWPLAN_ALL ON
    GO
    DECLARE @nv nvarchar;SELECT * FROM _t WHERE c = @nv; -- nvarchar
    GO
    SET SHOWPLAN_ALL OFF;
    GO
    

    结果例如以下图所看到的:
    这里写图片描写叙述

    无论是varchar,还是nvarchar的变量。预估的行数都是99.0099。这个值与使用nvarchar常量值的结果一样,看来SQL Server查询优化器应该确实把 GetRangeThroughConvert 的结果看成变量了。这个应该是设计上考虑不太周全的地方了,毕竟指定固定常量值的时候,GetRangeThroughConvert的结果应该也是确定值才对。(这个问题在 SQL Server 2014中看起来是调整过来了,在2014中測试没有发现这种现象)。

  • 相关阅读:
    【Leetcode】【Easy】Remove Duplicates from Sorted List
    【Leetcode】【Easy】Pascal's Triangle II
    【Leetcode】【Easy】Pascal's Triangle
    【Leetcode】【Easy】Binary Tree Level Order Traversal II
    【Leetcode】【Easy】Binary Tree Level Order Traversal
    【Leetcode】【Easy】Maximum Depth of Binary Tree
    【Leetcode】【Easy】Minimum Depth of Binary Tree
    【Leetcode】【Easy】Balanced Binary Tree
    【Leetcode】【Easy】Symmetric Tree
    如何使用Action.Invoke()触发一个Storyboard
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7233878.html
Copyright © 2020-2023  润新知