2012-01-17 59 views
3

我需要在大約150,000行的表上搜索一個文本字段(varchar 500)。在大桌子上搜索文字的最有效方法是什麼?

Select p.ProductID, 
    p.ProductDescription, 
    p.SalesPrice 
From Products p 
Where p.ProductDescription Like '%' + @PartialDescription + '%' 

結果是相當緩慢:

我嘗試的第一個選項是直接它看起來像在數據庫服務器上執行的存儲過程。即使使用ProductDescription索引,性能也不夠快。

我在下面的步驟與作品來到了下一個解決方案:

  1. 閱讀整個產品表到產品類型列表,並將它緩存。
  2. 每次我需要做一個搜索,我去通過收集和做字符串對比如下

    List<Product> searchResultItems = new List<Product>(); 
    for (int i = 0; i < cachedProducts.Count; i++) 
    { 
        Product p = cachedProducts[i]; 
    
        if (p.Description.IndexOf(partialDescription, StringComparison.OrdinalIgnoreCase)>=0) 
        { 
         searchResultItems.Add(p); 
        } 
    } 
    return searchResultItems; 
    

這個解決方案不是直接搜索到數據庫快一點。 通過在內存中緩存表,它可以在很大程度上避免數據庫調用。然而,它與傳統系統(FileMaker 10多年前構建的)相比仍然很慢。 我無法訪問遺留系統的源代碼,不太瞭解它。

使用MS SQL Server 2008數據庫,使用C#編寫的代碼和使用System.Runtime.Caching上的ObjectCache的緩存,我期待我的解決方案輕鬆勝過傳統系統。令人尷尬的是,事實並非如此。 如何優化我的搜索方法?我究竟做錯了什麼?上面的函數駐留在WCF服務中,並且由Web應用程序使用(basicHttpBinding)而沒有任何花哨的控制。我能做些什麼來使其更快?

直接搜索數據庫,它可以是任何優化的更好的解決方案嗎?我怎樣才能優化它?

回答

4

由於您正在使用通配符前綴搜索值,因此索引將無法使用,因此它將始終執行表掃描。您可以查看Full Text Search

+0

因此,搜索數據庫級別(與FTS)是最好的?沒有任何意義在應用層中完成它? (對@Alok也是同樣的問題)任何見解? – Romeo 2012-01-17 11:53:29

+0

恕我直言,除非你正在處理少量的行,那麼我會在數據庫級別。返回所有行並在應用程序層執行它對於大量數據來說並不會很好。 – AdaTheDev 2012-01-17 11:57:47

+0

謝謝,會嘗試FTS。 – Romeo 2012-01-17 12:02:23

5

如果您使用MS SQL 2008,我會建議使用全文搜索。在您的表上啓用FT索引,然後按照FTS提示搜索文本。

1

即使索引在ProductDescription上,性能還是不夠快。

SQL初學者:

'%' + @PartialDescription + '%'

Triggersa全表掃描,一個索引不能使用,因爲beginnnign的 「%」 。標準指數用於搜索單個詞。

如果你能處理移除 - 那麼基本上你索引的使用,應該立即得到回報

桌子上有15萬行

玩具的大小。除非你使用2GB vps運行。

我會消除%或轉到全文索引。

+0

一張有150,000行的表格是你的「玩具」嗎?你先生,是一個非常聰明的人。 +1非常令人鼓舞的評論。我現在回到我的桌子上玩玩具。 謝謝。 – Romeo 2012-01-17 22:34:08

+0

是。我生活在一個世界上,你每天將4000萬行的數據加載到表格中。我們在7分鐘內處理450.000個業務對象 - 其中一些具有近20個二十五萬個細節行。 10年前150.000人很小。 20年前,foxpro在處理有100萬條記錄的行時沒有問題。變得真實 - 今天你的小型工作站擁有16GB內存,250GB內存的數據庫服務器。 – TomTom 2012-01-18 05:52:36

相關問題