Questions tagged «cardinality-estimates»

1
SQL Server 2014:有关不一致的自连接基数估计的任何解释?
考虑SQL Server 2014中的以下查询计划: 在查询计划中,自联接ar.fId = ar.fId产生的估计值为1行。但是,这在逻辑上是不一致的估计:ar只有20,608行,并且只有一个不同的值fId(准确地反映在统计数据中)。因此,此联接产生行(~424MMrow)的全叉积,导致查询运行几个小时。 我很难理解为什么SQL Server会提出一个很容易证明与统计数据不一致的估计。有任何想法吗? 初步调查和其他细节 根据Paul 在这里的答案,似乎用于估计联接基数的SQL 2012和SQL 2014启发式方法应该可以轻松处理需要比较两个相同直方图的情况。 我从跟踪标志2363的输出开始,但无法轻松理解。下面的代码段是否表示SQL Server正在比较的直方图fId和bId以便估计仅使用的联接的选择性fId?如果是这样,那显然是不正确的。还是我误读了跟踪标志输出? Plan for computation: CSelCalcExpressionComparedToExpression( QCOL: [ar].fId x_cmpEq QCOL: [ar].fId ) Loaded histogram for column QCOL: [ar].bId from stats with id 3 Loaded histogram for column QCOL: [ar].fId from stats with id 1 Selectivity: 0 请注意,我想出了几种变通办法,这些变通办法包含在完整的repro脚本中,并将此查询缩短为毫秒。这个问题的重点是了解行为,如何在以后的查询中避免它,以及确定它是否应与Microsoft一起提交。 …

2
为什么LEN()函数严重低估了SQL Server 2014中的基数?
我有一个带有字符串列和谓词的表,该谓词检查具有一定长度的行。在SQL Server 2014中,无论我要检查的长度如何,我都会看到1行的估计。这产生了非常糟糕的计划,因为实际上有成千上万甚至上百万的行,并且SQL Server选择将此表放在嵌套循环的外侧。 对于SQL Server 2014的基数估计为1.0003,而SQL Server 2012的基数估计为31,622,是否有解释?有没有好的解决方法? 以下是问题的简短摘要: -- Create a table with 1MM rows of dummy data CREATE TABLE #customers (cust_nbr VARCHAR(10) NOT NULL) GO INSERT INTO #customers WITH (TABLOCK) (cust_nbr) SELECT TOP 1000000 CONVERT(VARCHAR(10), ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS cust_nbr FROM master..spt_values v1 CROSS …

2
为什么子查询将行估算值减少到1?
考虑以下人为但简单的查询: SELECT ID , CASE WHEN ID <> 0 THEN (SELECT TOP 1 ID FROM X_OTHER_TABLE) ELSE (SELECT TOP 1 ID FROM X_OTHER_TABLE_2) END AS ID2 FROM X_HEAP; 我希望此查询的最终行估计等于X_HEAP表中的行数。无论我在子查询中执行的操作与行估计无关紧要,因为它无法过滤出任何行。但是,在SQL Server 2016上,由于子查询,我看到行估计减少为1: 为什么会这样?我该怎么办? 使用正确的语法很容易重现此问题。这是一组可以做到的表定义: CREATE TABLE dbo.X_HEAP (ID INT NOT NULL) CREATE TABLE dbo.X_OTHER_TABLE (ID INT NOT NULL); CREATE TABLE dbo.X_OTHER_TABLE_2 …

2
LIKE运算符的基数估计(局部变量)
我给人的印象是,LIKE在对未知场景进行所有优化时都使用运算符时,旧的和​​新的CE都使用9%的估计值(假设相关统计数据可用并且查询优化器不必求助于选择性猜测)。 当对信用数据库执行以下查询时,在不同的CE下我得到了不同的估计。在新的CE下,我收到了900行的估计值,而在旧的CE下,我收到了241.416的估计值,我不知道如何得出此估计值。有人能说清楚吗? -- New CE (Estimate = 900) DECLARE @LastName VARCHAR(15) = 'BA%' SELECT * FROM [Credit].[dbo].[member] WHERE [lastname] LIKE @LastName; -- Forcing Legacy CE (Estimate = 241.416) DECLARE @LastName VARCHAR(15) = 'BA%' SELECT * FROM [Credit].[dbo].[member] WHERE [lastname] LIKE @LastName OPTION ( QUERYTRACEON 9481, QUERYTRACEON 9292, QUERYTRACEON 9204, QUERYTRACEON …

2
为什么串联运算符估计的行数少于其输入的行数?
在下面的查询计划摘要中,很明显,该Concatenation运算符的行估计应为~4.3 billion rows,或其两个输入的行估计之和。 但是,~238 million rows会产生一个估计值,从而导致次优Sort/ Stream Aggregate策略,该策略会将数百GB的数据溢出到tempdb。在这种情况下,逻辑上一致的估计将产生Hash Aggregate,消除了溢出,并显着提高了查询性能。 这是SQL Server 2014中的错误吗?在任何合理的情况下,估算值低于输入值可能是合理的?可能有哪些解决方法? 这是完整的查询计划(匿名)。我没有对该服务器的sysadmin访问权限,无法提供来自QUERYTRACEON 2363或类似跟踪标记的输出,但是如果有帮助的话,也许可以从管理员那里获取这些输出。 该数据库的兼容性级别为120,因此正在使用新的SQL Server 2014基数估计器。 每次加载数据时都会手动更新统计信息。给定数据量,我们当前正在使用默认采样率。较高的采样率(或FULLSCAN)可能会产生影响。

3
为什么这个连接基数估计值这么大?
我遇到以下查询的基数估计过高: SELECT dm.PRIMARY_ID FROM ( SELECT COALESCE(d1.JOIN_ID, d2.JOIN_ID, d3.JOIN_ID) PRIMARY_ID FROM X_DRIVING_TABLE dt LEFT OUTER JOIN X_DETAIL_1 d1 ON dt.ID = d1.ID LEFT OUTER JOIN X_DETAIL_LINK lnk ON d1.LINK_ID = lnk.LINK_ID LEFT OUTER JOIN X_DETAIL_2 d2 ON dt.ID = d2.ID LEFT OUTER JOIN X_DETAIL_3 d3 ON dt.ID = d3.ID ) …

1
查询计划“基数估计”中的警告
create table T(ID int identity primary key) insert into T default values insert into T default values go select cast(ID as varchar(10)) as ID from T where ID = 1 上面的查询在查询计划中有一个警告。 <Warnings> <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT(varchar(10),[xx].[dbo].[T].[ID],0)" /> </Warnings> 为什么会有警告? 字段列表中的类型转换如何影响基数估计?

1
SQL Server 2014 COUNT(DISTINCT x)忽略列x的统计信息密度向量
对于COUNT(DISTINCT)具有约10亿个不同值的,我正在获得一个查询计划,该计划的哈希汇总估计只有300万行。 为什么会这样呢?SQL Server 2012提供了一个很好的估计,所以这是我应该在Connect上报告的SQL Server 2014中的错误吗? 查询和差评 -- Actual rows: 1,011,719,166 -- SQL 2012 estimated rows: 1,079,130,000 (106% of actual) -- SQL 2014 estimated rows: 2,980,240 (0.29% of actual) SELECT COUNT(DISTINCT factCol5) FROM BigFactTable OPTION (RECOMPILE, QUERYTRACEON 9481) -- Include this line to use SQL 2012 CE -- Stats for …

1
直方图以外的基数估计
设定 我在了解基数估算值时遇到了一些麻烦。这是我的测试设置: 2010版本的Stack Overflow数据库 SQL Server 2017 CU15 + GDR(KB4505225)-14.0.3192.2 新CE(兼容级别140) 我有这个过程: USE StackOverflow2010; GO CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount @CommentCount int AS BEGIN SELECT * FROM dbo.Posts p WHERE p.CommentCount = @CommentCount OPTION (RECOMPILE); END; GO dbo.Posts表上没有非聚集索引或统计信息(上有聚集索引Id)。 当要求为此的估计计划时,出来的“估计行” dbo.Posts为1,934.99: EXEC #sp_PostsByCommentCount @CommentCount = 51; 当我要求估算的计划时,会自动创建以下统计信息对象: DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]); 其中的重点是: …

1
将溢出排序到tempdb,但估计的行等于实际的行
在最大内存设置为25GB的SQL Server 2016 SP2上,我们有一个查询,在一分钟内执行大约80次。该查询将大约4000页溢出到tempdb。这会在tempdb磁盘上导致大量IO。 当您查看查询计划(简化查询)时,您会看到估计的行数等于实际的行数,但仍然会发生溢出。因此,过时的统计信息不能成为问题的原因。 我做了一些测试,然后查询溢出到Tempdb: select id --uniqueidentifier from SortProblem where [status] ='A' order by SequenceNumber asc option (maxdop 1) 但是,如果我选择其他列,则不会发生溢出: select startdate --datetime from SortProblem where [status] ='A' order by SequenceNumber asc option (maxdop 1) 因此,我尝试“扩大” id列的大小: select CONVERT(nvarchar(512),id) from SortProblem where [status] ='A' order by SequenceNumber asc …

1
部分覆盖范围谓词的垂直度估计
目前,我正在尝试弄清楚SQL Server如何评估部分覆盖直方图步骤的范围谓词的基数。 在Internet上,在针对阶跃统计值和阶跃内统计值进行基数估计时,我遇到了一个类似的问题,保罗·怀特(Paul White)给出了一个相当有趣的答案。 根据Paul的回答,用于估计谓词> =和>的基数的公式(在这种情况下,我只对至少120的基数估计器模型感兴趣): 对于>: Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1))) 对于> =: Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1)) 我根据使用TransactionDate列的范围谓词以及“ 20140614”和“ 20140618”之间的日期时间范围,在AdventureWorks2014数据库的[Production]。[TransactionHistory]表上测试了这些公式的应用。 此范围的直方图步骤的统计信息如下: 根据公式,我计算出以下查询的基数: SELECT COUNT(1) FROM [AdventureWorks2014].[Production].[TransactionHistory] WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000' …

2
内部联接的基数估计问题
我正在努力理解为什么行估计是如此严重的错误,这是我的情况: 简单连接-使用SQL Server 2016 sp2(在sp1上存在相同问题),dbcompatiblity = 130。 select Amount_TransactionCurrency_id, CurrencyShareds.id from CurrencyShareds INNER JOIN annexes ON Amount_TransactionCurrency_id = CurrencyShareds.Id option (QUERYTRACEON 3604, QUERYTRACEON 2363); SQL估计1行,而SQL为107131,并选择做一个嵌套循环(链接到plan)。在CurrencyShareds上更新统计信息之后,估算就可以了,并选择了合并联接(链接到新计划)。一旦仅将一条记录添加到CurrencyShareds,统计信息就会“过时”,并且sql返回错误的估计。 我不太担心这个简单的查询,但这只是一个更大的查询的一部分,而这就是多米诺骨牌的开始... 为什么在100条记录表中添加一行会造成这种损坏?查看基数估计跟踪的输出时,我看到此警告,***WARNING: badly-formed histogram ***但在此主题上找不到更多信息。 这是基数估计的全部输出: Begin selectivity computation Input tree: LogOp_Join CStCollBaseTable(ID=1, CARD=107131 TBL: annexes) CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds) ScaOp_Comp x_cmpEq ScaOp_Identifier QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id …

1
对SQL Server 2016中包含SUBSTRING()的谓词的估计值的更改吗?
是否有任何有关SQL Server 2016更改的文档或研究,以了解如何估计包含SUBSTRING()或其他字符串函数的谓词的基数? 我要问的原因是我正在查看一个在兼容模式130下性能下降的查询,原因与与包含调用SUBSTRING()的WHERE子句匹配的行数估计值的更改有关。我已通过查询重写纠正了此问题,但我想知道是否有人知道SQL Server 2016中有关此区域更改的任何文档。 演示代码如下。在此测试用例中,估计值非常接近,但准确性取决于数据。 在测试用例中,在兼容级别120中,SQL Server似乎正在使用直方图进行估计,而在兼容级别130中,SQL Server似乎假定表中有固定的10%匹配。 CREATE DATABASE MyStringTestDB; GO USE MyStringTestDB; GO DROP TABLE IF EXISTS dbo.StringTest; CREATE TABLE dbo.StringTest ( [TheString] varchar(15) ); GO INSERT INTO dbo.StringTest VALUES ( 'Y5_CLV' ); INSERT INTO dbo.StringTest VALUES ( 'Y5_EG3' ); INSERT INTO dbo.StringTest VALUES ( 'ZY_NE' …

1
SQL Server的优化器如何估计联接表中的行数?
我在AdventureWorks2012数据库中运行此查询: SELECT s.SalesOrderID, d.CarrierTrackingNumber, d.ProductID, d.OrderQty FROM Sales.SalesOrderHeader s JOIN Sales.SalesOrderDetail d ON s.SalesOrderID = d.SalesOrderID WHERE s.CustomerID = 11077 如果查看估算的执行计划,则会看到以下内容: 初始索引查找(右上)使用IX_SalesOrderHeader_CustomerID索引并在文字11077上进行搜索。其估计值为2.6192行。 如果使用DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM,则表明值11077在两个采样键11019和11091之间。 11019和11091之间的不同行的平均数为2.619718,或舍入为2.61972,这是为索引搜索显示的估计行的值。 我不了解的部分是针对SalesOrderDetail表的聚集索引查找的估计行数。 如果我运行DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'): 因此,SalesOrderID(我要加入)的密度为3.178134E-05。这意味着1 / 3.178134E-05(31465)等于SalesOrderDetail表中唯一SalesOrderID值的数量。 如果在SalesOrderDetail中有31465个唯一的SalesOrderID,则分布均匀,每个SalesOrderID的平均行数为121317(总行数)除以31465。平均值为3.85561 因此,如果要循环遍历的估计行数是2.61972,并且要返回的平均值是3.85561,则我认为估计行数将是2.61972 * 3.85561 = 10.10062。 但是估计的行数是11.4867。 我认为我对第二个估算值的理解是不正确的,不同的数字似乎表明了这一点。我想念什么?

3
在SQL Server 2014中查询慢100倍,行计数假脱机行估计是罪魁祸首?
我有一个查询,该查询在SQL Server 2012中运行800毫秒,在SQL Server 2014中运行约170秒。我认为我已将其范围缩小到Row Count Spool运营商的基数估计不佳。我已经读过一些关于假脱机操作符的信息(例如,here和here),但是仍然难以理解以下几点: 为什么此查询需要Row Count Spool运算符?我认为正确性不是必需的,那么它试图提供什么特定的优化? 为什么SQL Server估计联接到Row Count Spool运算符会删除所有行? 这是SQL Server 2014中的错误吗?如果是这样,我将提交Connect。但是我想先加深了解。 注意:LEFT JOIN为了在SQL Server 2012和SQL Server 2014中都能达到可接受的性能,我可以将查询重新编写为或向表中添加索引。因此,此问题更多地是关于深入了解此特定查询和计划的,而较少涉及如何用不同的措词查询。 慢查询 有关完整的测试脚本,请参见此Pastebin。这是我正在查看的特定测试查询: -- Prune any existing customers from the set of potential new customers -- This query is much slower than expected in SQL Server 2014 SELECT …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.