我有一些需要临时表的sprocs.为了不对列类型(varchar有一定长度)进行硬编码,所以我不必在引用表模式发生变化时更改声明(即字段变长)我这样做(而不是创建表调用):
select orderId
into #sometmptbl
from orders
where 1=2
Run Code Online (Sandbox Code Playgroud)
但是,当你对此进行showplan时,它实际上似乎是转到表/索引:
陈述1的查询计划(第1行).
Run Code Online (Sandbox Code Playgroud)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.报表1的总估计I/O成本(第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.
Run Code Online (Sandbox Code Playgroud)
如果您将统计 io 设置为打开,您应该会看到零逻辑和物理读取。它可能会创建一个扫描索引的计划,但似乎并未实际使用它。
我建议不要在大批量生产环境中以这种方式创建临时表。存在系统表锁定问题,以及轻微的性能影响(您的情况可能会有所不同)。(列的标识属性也被转移到临时表中)。
作为快捷方式 - 我将 1=2 写入显式 tempdb..MyScratchTable,然后使用 RapidSQL(或其他一些工具)从该临时表生成 DDL。
如果它是 varchar,那么没有任何理由不能标准化最大值的列长度并在任何地方使用它。