我有一些需要临时表的sprocs。为了不对列类型(varchar有一定长度)进行硬编码,所以我不必在引用表模式发生变化时更改声明(即字段变长)我这样做(而不是创建表调用):
select orderId
into #sometmptbl
from orders
where 1=2
然而,当你对此进行showplan时,它实际上似乎是要进入表/索引:
陈述1的查询计划(在线 1)。
STEP 1 The type of query is CREATE TABLE. STEP 2 The type of query is INSERT. The update mode is direct. FROM TABLE orders Nested iteration. Index : orders_idx1 Forward scan. Positioning at index start. Index contains all needed columns. Base table will not be read. Using I/O Size 2 Kbytes for index leaf pages. With LRU Buffer Replacement Strategy for index leaf pages. TO TABLE #sometmptbl Using I/O Size 2 Kbytes for data pages.
声明的总估计I / O成本 1(第1行):632082。
这是否意味着对索引中的每个条目评估1 = 2?有没有办法在一个恒定的时间内做到这一点?
更新:
以下是执行后的实际I / O开销,因此看起来实际读取确实为0,因此不会对性能产生影响:
Table: orders scan count 0, logical reads: (regular=0 apf=0 total=0), physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Table: #sometmptbl_____00002860018595346 scan count 0, logical reads: (regular=1 apf=0 total=1), physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Total actual I/O cost for this command: 2.
Total writes for this command: 3
0 row(s) affected.
答案 0 :(得分:4)
如果设置了统计信息,则应该看到逻辑和物理读取为零。 它可能会创建一个扫描索引的计划,但似乎并没有实际使用它。
我建议不要在大批量生产环境中以这种方式创建临时表。系统表锁定问题,以及轻微的性能损失(您的里程可能会有所不同)。 (列的标识属性也会被转移到临时表中)。
作为一种捷径 - 我将1 = 2转换为显式的tempdb..MyScratchTable,然后使用RapidSQL(或其他工具)从该临时表生成DDL。
如果它是一个varchar,那么就不应该有任何理由不能在最大值上标准化列长度而只是使用它。
答案 1 :(得分:0)
select orderId from orders where 1=2
给你什么?
它可能选择了索引来读取数据类型等,而一个非常简单的查询(没有INTO)应该被优化而根本没有表/索引访问。