11

我有一張表,我已經創建了一個全文目錄。桌子剛剛超過6000行。我在索引中添加了兩列。第一個可以被認爲是各種唯一的標識符,第二個可以被認爲是該項目的內容(我的表格中有11個其他列,不是全文目錄的一部分)。這是一對夫婦行的例子:全文索引呆滯。尋找替代品

TABLE: data_variables 
ROW unique_id label 
1  A100d1  Personal preference of online shopping sites 
2  A100d2  Shopping behaviors for adults in household 

在在前端我的web應用程序,我有一個文本框,用戶可以鍵入拿到賽他們任何條款的項目清單搜索UNIQUE IDLABEL列。因此,例如,如果用戶在shoa100中鍵入,則列表將填入上面的兩行。如果他們輸入behav那麼只有上面的第2行填充一個列表。

這是通過每個keyup上的Ajax請求完成的。 PHP調用看起來像SQL服務器上的存儲過程:(@search是從傳遞到存儲過程的用戶的文本)

SELECT TOP 50 dv.id, dv.id + ': ' + dv.label, 
       dv.type_id, dv.grouping, dv.friendly_label 
FROM   data_variables dv 
WHERE   (CONTAINS((dv.unique_id, dv.label), @search)) 

我注意到,這得到相當低迷,尤其是當我在查詢中不使用TOP 50時。

我在尋找的是直接在SQL Server上或通過放棄全文索引的想法,並使用jQuery來搜索客戶端上的可搜索項目數組來加速這種方式。我已經看了一下jQuery自動完成的東西和一些其他的自動完成的jQuery插件,但還沒有試圖模擬任何東西。這將是我的下一步,但我想首先在這裏查看,看看我會得到什麼建議。

在此先感謝。

+4

你能確認你已經測量單獨的SQL性能,而不是隻用你的網頁?如果你正在使用網頁來測試它,那麼很多其他的事情可能是這個問題,確定你知道這一點,只是想仔細檢查。當你輸入更長的搜索字符串時,它會變得更快嗎?如果是的話,這意味着它不是sql – rlb 2013-03-02 20:19:06

+0

'這是通過每個keyup上的Ajax請求完成的 - 在這種情況發生之前是否有最小長度?這是我的寵兒之一,所以我不會喋喋不休,但當頁面吞掉了我的前幾個按鍵時,我確實討厭它。從性能角度來看,在調用全文搜索之前等待至少三或四個字符可能會更好。最初的幾次檢索帶回了小船。即使你在調用之前等待幾個字符,我也不會期望它能很好地擴展。而且我知道,由於雲延遲問題,它在雲中的分貝數據庫上效果不佳。 – Tim 2013-03-09 11:07:59

+0

提姆:是的 - 它在2次按鍵後觸發。我無法做更多,因爲有唯一的ID只有兩個字符長。 – tptcat 2013-03-09 18:40:25

回答

5

幾個建議,基於你只有6000行的事實,所以數據庫應該活着吃這個。答:請嘗試使用Like運算符,以防萬一。不要期待它,但嘗試很微不足道。這裏還有一些其他的事情可以讓你在這些小卷的情況下檢測到這個速度很慢。 B.你能提前緩存查詢嗎?對於6000行,可能只有36 * 36個2個字符查詢的組合,這應該幾乎不需要內存並可以保存數據庫的任何工作。

C.將選擇移出到客戶端是一個好主意,取決於6000行的整體大小,還是單個查找的網絡延遲。

D.結合b和c將給你真正的好表現,我懷疑,但需要一些編碼工作。如果服務器維護緩存中所有單字符結果的列表,並且客戶端在第一次擊鍵後下載字母緩存集,則它們可能具有所有行的子集,但不需要爲額外擊鍵執行更多網絡IO。

+0

我要給你賞金,肋骨,以便對我原來的帖子發表評論。我對我的查詢做了一些更完整的測量,真正的問題是我的前端。我將努力優化,因爲這似乎是真正放緩的地方。感謝大家的建議。 – tptcat 2013-03-09 18:44:07

2

如果您計劃增加數據量,這將是使用反向索引進行全文搜索的最佳方法。

Apache Solr - 此刻最好的全文搜索引擎。

你可以簡單地定期索引你的數據庫數據,並使用solr作爲搜索引擎, 它提供了簡單的ajax API,可以直接從前端查詢。

+0

從個人經驗solr選項是好的,如果數據必須只讀只是數據檢索作業必須完成,但如果數據必須頻繁上傳,然後更新/維護solr索引可能是一個昂貴的/繁忙的任務 – Rafay 2013-03-09 12:51:35

+0

索引可以分解爲這種用例。 – Nik 2013-03-11 08:32:38

5

我有同樣的問題,並去了類似的解決方案。我也發現操作符太費稅了,並且將查詢分成兩個選項,並且全部爲聯合(最快,在我的場景中,在索引列和數據中找不到相同的文本)。

你的將是像

SELECT TOP 50 from (
select dv.id, dv.id + ': ' + dv.label, 
       dv.type_id, dv.grouping, dv.friendly_label 
FROM   data_variables dv 
WHERE   dv.unique_id like '%'[email protected]+'%' 
UNION ALL 
select dv.id, dv.id + ': ' + dv.label, 
       dv.type_id, dv.grouping, dv.friendly_label 
FROM   data_variables dv 
WHERE   dv.label like '%'[email protected]+'%' 
) 

哦!並測試SQL Server中的性能,而不是網絡!

6

我會建議對一個LIKE,除非您使用的是線性指標(左到右)和你正在做的查詢,如LIKE 'work%'。如果你正在做類似LIKE '%word%'的常規索引不會幫助你。當您想要在段落內搜索單詞時,通常需要使用全文索引。

有了大量的數據,通常內置在數據庫中全文引擎都不是很竊取。爲了獲得最佳性能,您通常必須使用專門爲Full-Text構建的外部解決方案。

一些選項是Sphinx,Solrelasticsearch,僅舉幾例。我不會說任何這些選擇都比其他選項好。有一定的利弊考慮:

  • 你有什麼樣的數據?
  • 這些解決方案有哪些語言支持?
  • 這些解決方案支持哪些數據庫引擎?

你能做的最好的事情是對基準現有數據這些解決方案。測試每個單獨的組件(單元測​​試)可以幫助您識別真正的問題並幫助您找到最佳的解決方案。

0

如果你真的需要性能..你可能想看看; FTS3和FTS4 ...

喀嚓......從另一個論壇...

例如,如果每個在「安然電子郵件數據集的」 517430個文檔插入既是FTS表使用以下SQL腳本創建的普通SQLite表:

代碼: CREATE VIRTUAL TABLE enrondata1 USING fts3(content TEXT);/* FTS3表/ CREATE TABLE enrondata2(content TEXT);/普通表*/ 以下兩個查詢然後要麼可以執行發現的包含單詞「LINUX」數據庫中的文檔數量(351)。使用一臺臺式PC硬件配置,FTS3表上的查詢大約在0.03秒內返回,而查詢普通表時則爲22.5秒。

看到...

http://www.sqlite.org/fts3.html