2011-03-03 40 views
3

我有創建和使用臨時#tableSybase存儲過程 - 如何在#table上創建索引?

一些疑問會如果臨時#table會對它創建了一個索引來優化極大作品的存儲過程。

然而,在存儲過程中創建索引失敗:

create procedure test1 as 
SELECT f1, f2, f3 
INTO #table1 
FROM main_table 
WHERE 1 = 2 

-- insert rows into #table1 

create index my_idx on #table1 (f1) 

SELECT f1, f2, f3 FROM #table1 (index my_idx) WHERE f1 = 11 -- "QUERY X" 

當我調用上面,對於「QUERY X」的查詢計劃顯示錶掃描。

如果我只是在存儲過程外運行上面的代碼,該消息將顯示以下警告:

指數「my_idx」在指定爲優化器提示的FROM表「#表1」的條款不存在。優化器會選擇另一個索引。

這可以通過addding「走出去」創建了索引之後分兩批分裂上面的代碼運行的ad-hoc(存儲過程外)時得到解決:

create index my_idx on #table1 (f1) 
go 

現在,「QUERY X 「查詢計劃顯示使用索引」my_idx「。

問題:在存儲過程中,我該如何在單獨的批處理中運行「創建索引」?我不能像在上面的特設副本那樣插入「去」。請注意,我知道「將QUERY X'分解爲單獨的存儲過程」的解決方案,並且正在尋找可以避免這種情況的解決方案。

P.S.如果它的事項,這是基於Sybase 12(ASE 12.5.4)


UPDATE

我已經看到多次提到 「模式碰撞」 我的谷歌搜索在提出這個問題之前。但這似乎並不發生在我的情況。

您可以創建一個表,填充它,在同PORC從它創建它的索引和選擇值 ,並有充分的成本它基於 準確的信息優化。這被稱爲'模式碰撞',自11.5.1起已經到位 。

回答

0

Sybase的文檔中說,創建並在同一個存儲過程中使用臨時指數:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc20023_1251/html/optimizer/X26029.htm

我覺得要解決這個問題,你需要將你的存儲過程分成至少兩個部分,一個創建並填充表,然後構建索引,然後第二個運行選擇查詢。

+1

我在問題中明確聲明'請注意,我意識到「將'QUERY X'拆分爲單獨的存儲過程'的解決方案」,並且正在尋找一種避免這種情況的解決方案。 – DVK 2011-07-21 17:55:24

0

我不確定你是如何解決這個問題的,可能是Sybase的舊版本,但是12.5版本。4我嘗試執行與你所建議的相同的事情,但在我的情況下,優化器正確地建議使用在存儲過程中創建的索引。通常在存儲過程中,我們不需要將sql分解爲批處理,因爲除此之外,我們還需要爲create table命令創建一個單獨的批處理。

如果我們嘗試在同一批次(而不是存儲過程)中創建索引,我們將獲得與上面指定的相同的錯誤,因爲我們試圖在表上創建索引,然後嘗試使用它在同一批次內。通常Sybase服務器會一次編譯整個批次,因此會出現問題。但就Sybase 12.5.4中的存儲過程而言,不存在任何問題。