轉自Carfield的貓窩SQL Server全文索引的個人總結(上)
大家都知道LIKE查詢很慢,全文索引就是事先做好相關的索引,表示哪個主題詞可以在哪些記錄裡找到,甚至事先計算好RANK,檢索時可以把相關度高的先列出來,這可以大大提高檢索的速度。
打個比方,你有很多的小抽屜,每個抽屜裡面放一些雜物,假如你要找東西,最原始的方法就是一個個抽屜翻,這就是沒有索引的情況。
假如聰明一點,給抽屜編號(唯一鍵),把哪個號碼的抽屜有什麼東西記錄在紙上,找東西先看看這張紙,這就是普通索引,假如你要知道哪個抽屜有什麼,你可以在紙上迅速找到抽屜號碼(大家知道這是使用尋找樹),然後得到相關的資訊,這種情況普通索引是很快的;但是要找到一個特定的東西哪些抽屜有,你就要把整張紙遍曆一次,這就是LIKE查詢,假如你要找哪些抽屜同時有2種甚至更多種物品,LIKE就更加繁瑣了。假如一個表有上千萬的紀錄,大家可以想象查詢的代價。
可以換一個思路,另外找張紙,記錄一樣東西存在於哪些抽屜:
夾子:1,3,4,5,6,9,12...
錢幣:2,3,4,7,12...
藥丸:1,3,5,6...
這樣找到某樣東西或者某幾樣東西都很容易。
全文索引和普通的SQL索引有很多的區別:
普通 SQL 索引 |
全文索引 |
儲存時受定義它們所在的資料庫的控制。 |
儲存在檔案系統中,但通過資料庫管理。 |
每個表允許有若干個普通索引。 |
每個表只允許有一個全文索引。 |
當對作為其基礎的資料進行插入、更新或刪除時,它們自動更新。 |
將資料添加到全文索引稱為填充,全文索引可通過調度或特定請求來請求,也可以在添加新資料時自動發生。 |
不分組。 |
在同一個資料庫內分組為一個或多個全文檢索目錄。 |
使用 SQL Server 企業管理器、嚮導或 Transact-SQL 陳述式建立和除去。 |
使用 SQL Server 企業管理器、嚮導或預存程序建立、管理和除去。 |
使用全文索引的話,可以看看下面的文章(感謝大力和lihonggen0):
???? 如何在sqlserver中建立全文索引:
???? http://www.csdn.net/develop/Read_Article.asp?Id=17137
???
???? 如何使用image欄位:
???? http://expert.csdn.net/Expert/topic/1594/1594455.xml
發現大家有一個常問的問題,就是關於以下的資訊的:
查詢子句只包含被忽略的詞
這是因為使用一些很簡單的詞,比如'是',進行查詢的緣故。
提出的解決辦法不外乎是把C:\Program Files\Microsoft SQL Server\MSSQL\FTDATA\SQLServer\Config\noise.chs 清空
覺得這種方法是不可取的,大家開啟這個檔案看看,發現裡面是一些這樣的詞:is,are,be,at,我,是
這些詞都是頻率很高的詞,而且在查詢中的意義不大,就好像幾乎每個抽屜裡面都有紙屑一樣,為這些詞作索引得不償失,所以全文引擎把這些詞稱為非搜尋字不做索引,個人覺得在應用中過濾這些詞然後向使用者提出友好的提示更好,而不是使用清空noise.chs粗暴的對待全文引擎。比方大家可以看看在Google中搜尋“的”
-------------------------------------------------------------------------
另外謝謝ghj,一個很重要的東西遺漏了,與一般的索引立即更新不同,全文索引一般是定期維護索引的,所以對於頻繁更新的資料不合適,需要做全文索引的對象一般都是論文網頁之類,還算適合拉!
個人覺得我的資料庫沒有代表性,所以也不細說:作索引的時候,CPU和記憶體使用量都很高,時間也很長(下面我的資料庫是整個晚上),完成以後並不需要使用很多的系統資源,多個全文檢索查詢並發的時候也有不小的CPU消耗,但是比LIKE強。
我的系統上資料庫是123M,太小,使用全文索引沒有感到特別的優勢,但是可以想想對於GOOGLE那樣的海量資料,使用LIKE是不可想象的:)當然別人也沒有使用關聯式資料庫。
SQL Server全文索引的個人總結(下)-關於中文分詞
在使用SQL Search的過程中,還發現了一個問題:它對中文,是按字分詞的,下面我解釋一下:
比如對'部落格堂成員很多是MVP'這句話,假如一個個的字的作索引,會比使用'部落格堂','成員',MVP'幾個詞作索引產生的索引大很多,這樣不僅浪費空間,也影響索引的效率和準確度。假如英文是按照字母而不是單詞作索引,估計世界上如今就沒有全文索引,也沒有google了。
但是中文在分詞上,相比英文有天然的屏障,英文的單詞之間有間隔,但是中文不是,必須使用電腦的人工智慧把句子分成一個個的詞,有些時候,根據句子本身還不夠,還必鬚根據上下文,或者一些日常知識才能判斷。比如 乒乓球拍/賣/完了 和 乒乓球/拍賣/完了 ,電腦咋能知道是哪個意思並正確分詞呢!
根據使用的結果,SQL Search對中文使用的應該是按字分詞(可能是因為原來是英文引擎的緣故),比方說你要查'馬克',它會把'馬克思'也給你倒騰出來。
我的一個123M的資料庫,全文索引有55M,每次全文檢索查詢都比較慢(當然機器也很次)。
--------------------------------------------------------------------------------------------------
關於按字分詞:
應該還是怡紅公子的說法比較妥當,大家看看這個句子:
作業系統能否用匯騙語言改寫限制它對每個連接埠的使用率
為了驗證分詞,故意使用錯誤的分詞,假如都可以索引出該句子,就說明是按字分詞的。比如使用 '用匯' ?查詢,也可以查出句子,所以得出了SQLServer按字分詞的結論,我沒有進一步檢查,但是現在發現使用'寫限',使用'統能'就無法查出來了,證明SQLServer中還是有簡單分詞的,只是分詞結果不理想。
此外,SQLServer還可以使用第三方的產品增強分詞的能力。
--------------------------------------------------------------------------------------------------
假如對分詞有興趣的朋友,這裡有一些代碼可以看,使用發現分詞正確率還是很高的,不過要註冊才可以得到:http://www.nlp.org.cn/project/project.php?proj_id=6