Dan*_*lam 8 sql-server t-sql execution-plan cardinality-estimates
我最近在做一些性能测试时注意到了这一点。当我将一个值插入到需要隐式转换(例如bigint
into nvarchar
)的列中时,我收到一条警告:
表达式中的类型转换
(CONVERT_IMPLICIT(nvarchar(50),[tempdb].[dbo].[#MyFunIntTable].[EvenCoolerColumn],0))
可能会影响查询计划选择中的“基数估计”。
作为一个关心的公民,我检查了所有明显的嫌疑人,并最终深入研究了 XML 以确认它实际上是关于插入表的警告。问题是,我无法弄清楚为什么这会影响基数估计。如果我在连接中或在具有更多逻辑的地方执行此操作,那将是有道理的,但是实际插入操作不应该存在基数估计不匹配,对吗?
我注意到当它不仅仅是一个简单的查询时会发生这种情况 - 只要插入了多个值,或者我们从表中提取一个值,我们就会点击这个。
这个问题吸引了一些潜在的重复,包括:
我认为它与这些问题不同,因为我实际上没有对这个专栏做任何事情。我没有在过滤器、排序、分组、连接或函数中使用它 - 这些东西中的任何一个都会使场景变得更加复杂。我所做的只是将 a 插入bigint
到 a 中nvarchar
,这永远不会影响我能想到的有意义的基数估计。
我特别想从答案中寻找的是:
我用下面的简单例子重新创建了它(粘贴计划)
DROP TABLE IF EXISTS #MyFunStringTable;
DROP TABLE IF EXISTS #MyFunIntTable;
CREATE TABLE #MyFunStringTable
(
SuperCoolColumn nvarchar(50) COLLATE DATABASE_DEFAULT NULL
);
CREATE TABLE #MyFunIntTable
(
EvenCoolerColumn bigint NULL
);
INSERT INTO #MyFunIntTable
( EvenCoolerColumn )
VALUES
( 1 ),
( 2 ),
( 3 ),
( 4 ),
( 5 );
INSERT INTO #MyFunStringTable
( SuperCoolColumn )
SELECT EvenCoolerColumn
FROM #MyFunIntTable;
INSERT INTO #MyFunStringTable
( SuperCoolColumn )
VALUES
( 1 );
INSERT INTO #MyFunStringTable
( SuperCoolColumn )
VALUES
( 1 ),
( 2 );
INSERT INTO #MyFunStringTable
( SuperCoolColumn )
SELECT 1;
INSERT INTO #MyFunStringTable
( SuperCoolColumn )
SELECT 1
UNION ALL
SELECT 2;
INSERT INTO #MyFunStringTable
( SuperCoolColumn )
SELECT 1
FROM #MyFunIntTable;
Run Code Online (Sandbox Code Playgroud)
Pau*_*ite 10
与其他执行计划警告一样,这个警告是信息性的。如果您的查询执行缓慢,或者您注意到基数估计不正确,警告将提供有关在哪里寻找可能原因的信息。
作为一个纯粹的实际问题,这几乎是它的结束。触发此优化器警告的确切条件没有记录。
也就是说,我将详细介绍一下,以满足您的一点好奇心。
1. 解释为什么我在没有任何兴趣的情况下收到此警告 - 是否只是 SQL Server 会保守并报告,即使它不会影响计划选择?
查询优化器的基数估计组件有一些有趣的事情。该组件跟踪查询树中每个逻辑运算符的各种属性和其他信息。这包括直方图(来自磁盘,或完全在内存中派生)、域信息、函数依赖等。
在您的具体示例中,当已知转换的输入是单调的但输出不是时,将触发警告。从integer
文字到bigint
保留此属性的转换。从bigint
到nvarchar(50)
没有转换。
当存在单个文字整数常量时,解析时常量折叠会nvarchar
在优化开始之前将其转换为。这避免了计划中的类型转换以及相关的警告。
原始基数估计器和新基数估计器之间存在详细的内部实现差异,这意味着某些语句将在一个 CE 下生成警告,而不是在另一个 CE 下生成警告。
2. 什么基数估计在这里实际上存在风险,基于该基数估计的不准确,哪些操作会发生变化?
在您的示例语句中,没有。如前所述,转换可能会影响其他内部数据,这可能会影响其他计划运算符或通过优化器采用的代码路径。主要的一点是,要考虑的不仅仅是原始基数估计。内部差异可能会影响索引视图或计算列匹配等内容,以及其他可能性。
3. 是否存在这会影响计划选择的情况?显然,如果我开始加入或过滤转换后的列,它可以,但按原样?
这似乎与上一个问题相同。
4.除了改变数据类型之外,有没有什么办法可以防止它发出警告(假设这是数据模型如何交互的要求)
没有选项可以关闭这些警告。
归档时间: |
|
查看次数: |
458 次 |
最近记录: |