2009-08-24 95 views
15

我連接到一個表幾十個不同的時間,每一次,我加入(或過濾)的基礎上一列的SUBSTRING的結果(這是一個字符串,但左填充零,我不關心最後四位數字)。因此,儘管此列已編入索引,並且我的查詢將使用索引,但它執行了表掃描,因爲SUBSTRING本身未編入索引,因此SQL Server必須在加入之前對每一行進行計算。SQL Server - 計算列上的索引?

我正在尋找關於如何加快此過程的任何想法。目前,在表格上有一個視圖(這是一個「SELECT * FROM」,只是爲了給表格一個友好的名字),並且我正在考慮在計算的視圖中添加一列,然後對其編制索引。我接受其他建議,但 - 有什麼想法?

更多詳細信息: 我應該分享這個開始。該表從我們的計費系統接收復制,因此編輯底層表以添加計算列不是一個選項。任何計算列都必須添加到表格中的視圖上。此外,前導零並不總是前導零 - 他們有時是我不感興趣的其他數據。我想真正的問題是「如何在VARCHAR列的中間連接數據,同時還可以?使用索引全文搜索

澄清我的例子 我簡化了,但本質上,比方說我試圖查找值與以下值的列:

00000MoreStuff 
00000Whatever 
19834212345 
Houses12345837443GGD 
00000023456MoreStuff 

我對SUBSTRING(7,5)=「12345」的行感興趣,所以我想要第1-4行,但不是第5行。我提出的是addin g列到我的「SELECT *」視圖中,該視圖中包含此子字符串,然後基於該列進行索引。這是否更有意義?

+0

要使'JOIN'使用索引,您應該轉換您的列,以便它以您正在搜索的條件開始。至於現在,你的算法太模糊了。 「並不總是前導零的前導零」很難向SQL Server解釋。 'FULLTEXT'索引可以用來搜索單詞中的前綴(而不是整列),但是你仍然應該將數據分成單詞。你能否更清楚地定義你的搜索算法? – Quassnoi 2009-08-24 21:00:49

+0

如果您正在查看索引_SEEK_,那麼您還需要知道您的數據是否足夠有選擇性。也就是說,數據庫中的總值與預設值的數量之比是多少。 「交叉點」實際上很低(取決於表格的寬度)。另外,如果您的索引不包含您正在選擇的列,則您從書籤查找中執行的讀取次數將使SQL Server忽略您的全新索引。 您能否提供選擇性/選擇列表的詳細信息? – Anon246 2009-08-24 23:18:51

回答

13

假設你有你的字段的格式如下:

00Data0007 
000000Data0011 
0000Data0015 

,你可以做到以下幾點:

  • 創建一個計算列:ndata AS RIGHT(REVERSE(data), LEN(data) - 4)

    這將改變你的專欄分爲以下幾部分:

    ataD00 
    ataD000000 
    ataD0000 
    
  • 該列

  • 文檔版本創建索引這個查詢來搜索字符串Data

    SELECT * 
    FROM mytable 
    WHERE ndata LIKE N'ataD%' 
         AND SUBSTRING(ndata, LEN(N'ataD') + 1, LEN(ndata)) = REPLICATE('0', LEN(ndata) - LEN('ataD')) 
    

    第一條件將使用索引爲粗過濾。

    第二個將確保所有主要字符(即成爲計算列中的尾隨字符)都不是零而是零。

性能細節請參見我的博客此項:

更新

如果你只是想在SUBSTRING指數不改變你的模式,創建視圖是一種選擇。

CREATE VIEW v_substring75 
WITH SCHEMABINDING 
AS 
SELECT s.id, s.data, SUBSTRING(data, 7, 5) AS substring75 
FROM mytable 

CREATE UNIQUE CLUSTERED INDEX UX_substring75_substring_id ON (substring75, id) 

SELECT id, data 
FROM v_substring75 
WHERE substring75 = '12345' 
+0

這就是我最終要做的。我只是用圖表綁定視圖,然後我會很好。感謝指針。 – SqlRyan 2009-08-25 02:20:22

1

您是否可以用LIKE'something%'語句來重新定義您的過濾條件? (這適用於索引)

0

將列更改爲兩列 - 您加入的數據和額外的4個字符。 使用列的某些部分會減慢您看到的內容

6

的計算列添加到您的表中,並在此列上創建索引。

ALTER TABLE MyTable 
Add Column CodeHead As LEFT(Code,Len(Code)-4) 

然後在此創建一個索引。

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead