Mer*_*rik 7 sql-server indexing stored-procedures temp-tables
一位同事在一家使用 Microsoft SQL Server 的企业工作。他们的团队创建每天执行的存储过程以创建数据提取。基础表很大(有些有数十亿行),因此大多数存储过程的设计都是这样的:首先它们仅将这些巨大表的相关行提取到临时表中,然后临时表彼此连接并与其他较小的表连接。表来创建最终的摘录。与此类似的东西:
SELECT COL1, COL2, COL3
INTO #TABLE1
FROM HUGETABLE1
WHERE COL4 IN ('foo', 'bar');
SELECT COL1, COL102, COL103
INTO #TABLE2
FROM HUGETABLE2
WHERE COL14 = 'blah';
SELECT COL1, COL103, COL306
FROM #TABLE1 AS T1
JOIN #TABLE2 AS T2
ON T1.COL1 = T2.COL1
LEFT JOIN SMALLTABLE AS ST
ON T1.COL3 = ST.COL3
ORDER BY T1.COL1;
Run Code Online (Sandbox Code Playgroud)
通常,临时表在创建后不会被修改(因此没有后续的 ALTER、UPDATE 或 INSERT 操作)。出于本讨论的目的,我们假设临时表稍后仅使用一次(因此只有一个 SELECT 查询会依赖它们)。
这里的问题是:在创建这些临时表之后以及在后续查询中使用它们之前对这些临时表建立索引是一个好主意吗?
我的同事认为,创建索引将使联接和排序操作更快。不过,我相信总时间会更长,因为创建索引需要时间。换句话说,我假设除了边缘情况(例如临时表本身非常大,或者最终的 SELECT 查询非常复杂)之外,SQL Server 将使用临时表上的统计信息来优化最终查询,这样做时,它将有效地索引临时表,因为它认为合适。
换句话说,我习惯于认为只有当你知道表经常被使用时,创建索引才有用;一旦存储过程完成就被删除的一次性临时表不值得建立索引。
我们对 SQL Server 优化器的了解都不够,无法知道我们在哪些方面是对的,哪些方面是错的。您能否帮助我们更好地理解哪些假设更接近事实?
你的朋友可能是正确的,因为即使一个表将在单个查询中使用,而没有看到查询(即使我们看到了,我们仍然不太清楚它的执行计划是什么样子)我们有不知道 SQL Server 需要多少次在每个表的各个列中查找数据以进行连接、排序等。
然而,在两种方式实际完成并对结果进行测量和比较之前,我们永远无法确定。