哪些成本因素进入优化器,以选择不同类型的线轴?


15

线轴

在SQL Server中,有几种类型的线轴。我感兴趣的两个是Table SpoolIndex spool,它们在修改查询之外

只读查询(尤其是在嵌套循环联接的内侧)可以使用表或索引假脱机来潜在地减少I / O并提高查询性能。这些线轴可以是EagerLazy。就像你我一样。

我的问题是:

  • 哪些因素影响表与索引假脱机的选择
  • 哪些因素构成了热切线轴和惰性线轴之间的选择

Answers:


12

这有点宽泛,但是我认为我理解“真正的问题”,并将对此做出相应的回答。只是要谈论表vs索引假脱机。我认为在表和索引假脱机之间进行选择是不正确的。如您所知,有可能在单个子树中获取索引后台处理程序,表后台处理程序,或者同时获取索引后台处理程序和表后台处理程序。我认为在以下情况下获得索引假脱机通常是正确的:

  1. 查询优化器有理由将联接转换为应用
  2. 查询优化器实际上执行到应用的转换
  3. 查询优化器使用该规则添加索引假脱机(至少必须安全使用索引假脱机)
  4. 选择带有索引假脱机的计划

您可以通过简单的演示看到其中的大多数。首先创建一对堆:

DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_901;
CREATE TABLE dbo.X_10000_VARCHAR_901 (ID VARCHAR(901) NOT NULL);

INSERT INTO dbo.X_10000_VARCHAR_901 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;


DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_800;
CREATE TABLE dbo.X_10000_VARCHAR_800 (ID VARCHAR(800) NOT NULL);

INSERT INTO dbo.X_10000_VARCHAR_800 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

对于第一个查询,没有什么可以寻找的:

SELECT *
FROM dbo.X_10000_VARCHAR_901 a
CROSS JOIN dbo.X_10000_VARCHAR_901 b
OPTION (MAXDOP 1);

因此,优化器没有理由将联接转换为应用。由于成本原因,您最终得到了一个表假脱机。因此,此查询无法通过第一个测试。

在此处输入图片说明

对于下一个查询,可以合理地期望优化器有理由考虑应用:

SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID = b.ID 
OPTION (LOOP JOIN, MAXDOP 1);

但这并不意味着:

在此处输入图片说明

此查询第二次测试失败。完整的解释在这里。引用最相关的部分:

优化器不会考虑动态建立索引以启用应用;相反,事件的顺序通常是相反的:因为存在良好的索引,所以可以应用变换。

我可以重写查询,以鼓励优化器考虑应用:

SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (MAXDOP 1);

但是仍然没有索引假脱机:

在此处输入图片说明

该查询在第三次测试中失败。在SQL Server 2014中,索引键的长度限制为900字节。这在SQL Server 2016中得到了扩展,但仅适用于非聚集索引。线轴的索引是聚集索引,因此限制保持在900字节。在任何情况下,都不能应用索引假脱机规则,因为它可能导致查询执行期间出错。

将数据类型长度减少到800最终提供了一个带有索引假脱机的计划:

在此处输入图片说明

毫无疑问,索引假脱机计划的成本比没有假脱机的计划便宜得多:89.7603个单元对598.832个单元。您可以通过未记录的QUERYRULEOFF BuildSpool查询提示看到区别:

在此处输入图片说明

这不是一个完整的答案,但希望它是您想要的一些东西。

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.