2010-07-12 50 views
5

我有一些需要臨時表的sprocs。爲了不對列類型(具有一定長度的varchar)進行硬編碼,所以我不必在引用表模式更改時更改聲明(即字段變長),我這樣做(而不是create table調用):在哪裏1 = 2被調用每行?

select orderId 
into #sometmptbl 
from orders 
where 1=2 

但是,當你在這做一個顯示計劃實際上似乎是想表/索引:

查詢計劃語句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. 

估計總for語句 1(第1行)I/O成本:632082.

這是否意味着1 = 2被用於索引中的每個條目進行評估?有沒有辦法在一個固定的時間做到這一點?

更新

下面是實際的I/O成本執行(Execute),所以它看起來後像實際讀取確實是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. 

回答

4

如果設置的statistics io,您應該看到零邏輯和物理讀取。 它可能會創建一個計劃來掃描索引,但似乎並沒有實際使用它。

我建議不要在大批量生產環境中以這種方式創建臨時表。有系統表鎖定問題,以及輕微的性能影響(您的里程可能會有所不同)。 (也是列的標識屬性被轉移到臨時表中)。

作爲一個快捷方式 - 我將1 = 2放入顯式tempdb..MyScratchTable中,然後使用RapidSQL(或其他工具)從該scratch表中生成DDL。

如果它是一個varchar,那麼不應該有任何理由不能在最大值上標準化列長度,而只是使用那個地方。

+0

看起來你是對的 - 實際讀取爲0 – naumcho 2010-07-12 19:23:51

0

select orderId from orders where 1=2給你帶來了什麼?

它可能已經選擇了索引來讀取數據類型等,而一個非常簡單的查詢(沒有INTO)應該優化,根本沒有表/索引訪問。

相關問題