T-SQL 中临时表索引的最佳使用
-
09-06-2019 - |
题
如果您要在存储过程中创建临时表并希望在其上添加一个或两个索引,以提高针对该临时表执行的任何其他语句的性能,那么最好的方法是什么?赛贝斯 说 这:
“创建索引时表必须包含数据。如果创建临时表并在空表上创建索引,Adaptive Server 不会创建列统计信息,例如直方图和密度。如果在创建索引后插入数据行,优化器的统计信息是不完整的。”
但最近一位同事提到,如果我在与实际使用临时表不同的存储过程中创建临时表和索引,则 Adaptive Server 优化器 将要 能够利用它们。
总的来说,我不太喜欢那些没有什么价值的包装程序,所以我实际上还没有抽出时间来测试这个,但我想我应该把这个问题提出来,看看是否有人有其他的方法或建议?
解决方案
一些想法:
- 如果你的临时表太大以至于你必须对其建立索引,那么有没有更好的方法来解决这个问题呢?
您可以通过给出以下形式的优化器提示来强制它使用索引(如果您确定索引是访问表的正确方法):
SELECT * FROM #table (index idIndex) WHERE id = @id
如果您对一般性能技巧感兴趣,我在这里详细回答了其他几个相关问题:
其他提示
将数据放入临时表后添加索引会出现什么问题?
您需要注意的一件事是索引对可能同时运行的过程的其他实例的可见性。
我喜欢向此类临时表(以及索引)添加一个 guid,以确保永远不会发生冲突。这种方法的另一个好处是您可以简单地使临时表成为真正的表。
另外,请确保您需要查询这些临时表中的数据 不止一次 在存储过程运行期间,否则创建索引的成本将超过选择的好处。
在 Sybase 中,如果您创建一张临时表,然后在一个过程中使用它,则将使用表中估计的 100 行来构建选择计划。(该计划是在填充表之前启动过程时构建的。)这可能会导致临时表被表扫描,因为它只有“100 行”。调用另一个过程会导致 Sybase 使用实际行数构建选择计划,这允许优化器选择更好的索引来使用。我已经看到使用这种方法的显着改进,但在数据库上进行测试,因为有时没有区别。