sql全文索引
在Microsoft SQL Server 7.0 中提供了全文索引服務(Full-Text Search Service),在查詢性能上,對varchar,char,text類型的欄位的匹配查詢比用SQL語句使用Like操作符及匹配符的速度快10倍以上;在查詢匹配上,提供了模糊匹配的高級搜索性能並能夠返回查詢的命中率。 Full Text Search Service包含在SQL Server 7.0中,在SQL Server 7 Destop版中不起作用。安裝SQL Server時,無法預設安裝它,需要在Custom Installation 中選擇。 服務安裝完後在SQL Server EntERPrise Manager中的Support Services中顯示為Full-text Search,在控制面版中的服務中顯示為Microsoft Search.可以在SQL Server EnterPrise Manager中啟動這個服務,就可以在表中加入全文索引了。要注意:只有有唯一索引欄的表才能建立全文索引,並且全文索引建立好之後就不能改變表了,如要改變表就必須得取出索引,然後再裝入。
對表設置全文索引應用如下步驟:
1.選擇要建立全文索引的表,然後選擇: Full-Text Index Table ->Define Full-Text Indexing on a table
2.系統會啟動SQL Server Full-Text Index 向導。
3.選擇一個唯一索引。
4.選擇一個要建立索引的欄位。
5.選擇catalog。
6.選擇更新索引計劃(由於全文索引和普通索引表不同,不能自動更新,所以得加入一個計劃
)。
7.Finish。
8.選擇在資料庫Full-text catalogs中里的新建立的catalog,然後運行Start Population,Full Population 就可以了。
㈡ 建立全文檢索的sql語句
前言:微軟的SQL Server資料庫是一個在中低端企業應用中佔有廣泛市場的關系型資料庫系統,它以簡單、方便、易用等特性深得眾多軟體開發人員和資料庫管理人員的鍾愛。但SQL Server 7.0以前的資料庫系統由於沒有全文檢索功能,致使無法提供像文本內容查找此類的服務,成為一個小小的遺憾。從SQL Server 7.0起,到如今的SQL Server 2000終於具備了全文檢索功能,使用戶可以高效地檢索存儲在資料庫char、varchar、text、ntext、nchar、nvarchar等數據類型列中的文本數據。
建立全文索引
在進行全文檢索之前,必須先建立和填充資料庫全文索引。為了支持全文索引操作,SQL Server 7.0新增了一些存儲過程和Transact-SQL語句。使用這些存儲過程創建全文索引的具體步驟如下(括弧內為調用的存儲過程名稱):
1. 啟動資料庫的全文處理功能(sp_fulltext_
database);;
2. 建立全文檢索目錄(sp_fulltext_catalog);
3.在全文檢索目錄中注冊需要全文索引的表(sp_fulltext_table);
4. 指出表中需要全文檢索的列名(sp_fulltext_
column);;
5. 為表創建全文索引(sp_fulltext_table);;
6. 填充全文檢索目錄(sp_fulltext_catalog)。
下面舉例說明如何創建全文索引,在本例中,對Test資料庫Book表中Title列和Notes列建立全文索引。
use test //打開資料庫
//打開全文索引支持,啟動SQL Server的全文搜索服務
execute sp_fulltext_database 『enable』
//建立全文檢索目錄ft_test
execute sp_fulltext_catalog 『ft_test』, 『create』
為Title列建立全文索引數據元,pk_title為Book表中由主鍵所建立的唯一索引,這個參數是必需的。
execute sp_fulltext_table 『book』,『create』, 『ft_test』,『pk_title』
//設置全文索引列名
execute sp_fulltext_column 『book』, 『title』, 『add』
execute sp_fulltext_column 『book』,『notes』, 『add』
//建立全文索引
execute sp_fulltext_table 『book』, 『activate』
//填充全文索引目錄
execute sp_fulltext_catalog 『ft_test』, 『start_full』
至此,全文索引建立完畢。
進行全文檢索
SQL Server 2000提供的全文檢索語句主要有CONTAINS和FREETEXT。CONTAINS語句的功能是在表的所有列或指定列中搜索:一個字或短語;一個字或短語的前綴;與一個字相近的另一個字;一個字的派生字;一個重復出現的字。
CONTAINS語句的語法格式為:
CONTAINS({column | *}), <contains_search_condition> )
其中,column是搜索列,使用「*」時說明對表中所有全文索引列進行搜索。Contains_search_
condition 說明CONTAINS語句的搜索內容,其語法格式為:
{||||}[{{AND|AND NOT|OR}}] [...n]
下面就simple_term和prefix_term參數做簡要說明:
simple_term是CONTAINS語句所搜索的單字或短語,當搜索的是一個短語時,必須使用雙引號作為定界符。其格式為:
{『word』|「 phrase」}
prefix_term說明CONTAINS語句所搜索的字或短語前綴,其格式為:
{「word*」 | 「phrase*」}
例如,下面語句檢索Book表的Title列和Notes列中包含「database」或「computer」字元串的圖書名稱及其注釋信息:
select title, notes
from book
where contains(tilte, 『database』) or contains(notes,『database』)
or contains(title,『computer』) or contains(notes,『computer』)
FREETEXT語句的功能是在一個表的所有列或指定列中搜索一個自由文本格式的字元串,並返回與該字元串匹配的數據行。所以,FREETEXT語句所執行的功能又稱做自由式全文查詢。
FREETEXT語句的語法格式為:FREETEXT({column | * },『freetext_string』)
其中,column是被搜索列,使用「*」時說明對表中的所有全文索引列進行搜索。Freetext_string參數指出所搜索的自由文本格式字元串。
例如,下面語句使用FREETEXT語句搜索Book表中包含「Successful Life」字元串的數據行:
select title, notes
from book
where freetext(*,『Successful Life』)
㈢ 如何使用SQL Server中的全文索引
一般情況,使用SQL Server中的全文索引,經過大體4個步驟:
1). 安裝full text search全文索引服務;
2). 為數據表建立full text catalog全文索引目錄;
3). 進行full text catalog的population操作(使全文索引與數據表內容同步);
4). 使用全文索引進行查詢。
為了在數據表內容更新時全文索引資料庫的內容也保持最新,可以通過第5步建立full text catalog 的Population自動操作Schele.
http://jingyan..com/article/a681b0de0cc4023b1943467a.html
㈣ 為什麼說SQLServer全文索引有局限性
下面假設有這樣一個例子:在DataBase_name。dbo。Table_name中有一個名為Title(標題)和Contents(內容)的欄位,現在需要查詢在Title或者Contents中包括「qq」字元的所有記錄。 面對這樣的一個場景,我們通常都會寫這樣一個腳本:SELECT * FROM DataBase_name。
dbo。Table_name WHERE Title LIKE '%qq%' OR Contents LIKE '%qq%'; 沒錯,這也是我第一個想到的方法。但是我們需要思考的是:隨著時間的推移,數據會越來越大,那個時候我們該如何提高我們的性能?用戶隨時都有可能再添加對Remark(備注)欄位進行查找,難道我們就應該不厭其煩地修改程序代碼? 需要指出的是:面對這樣的查詢條件,即使Title和Contents上都有索引,我們也無法使用到索引,因為在 '%qq%'的「qq」前面使用了通配符,所以無法使用到索引;如果查詢的條件是'qq%',那到是可以利用上索引。
在許多資料庫性能調優的文章上都說OR這個謂詞可以使用SELECT UNION ALL SELECT這樣的方式來提高性能,但是需要提醒大家的是:如果在一條記錄中欄位Title和Contents都同時存在「中國」字元的話,那麼返回的結果就會出現兩條相同的記錄,如果你希望是唯一的記錄,那麼這個時候你就要注意了。
現在回到我們上面的問題,大概這個時候大家都應該想到了資料庫的全文索引了。全文索引是一種特殊類型的基於標記的功能性索引,由 Microsoft SQL Server 全文引擎 (MSFTESQL) 服務創建和維護。創建全文索引的過程與創建其他類型的索引的過程差別很大。
MSFTESQL 不是基於某一特定行中存儲的值來構造 B 樹結構,而是基於要索引的文本中的各個標記來創建倒排、堆積且壓縮的索引結構。(摘自MSDN) 為什麼說SQL Server 全文索引不是萬能的?可能大家都懷疑我是不是標題黨了,呵呵,馬上就講到,那就是這個全文索引能解決我們一開始提到的場景嗎?回答是否定。
為什麼呢?因為它的分詞和倒排索引造成了對字元串「tqq。tencent。com」這樣的內容進行『「*qq*」』這樣的條件查詢,上面那條記錄是不會被返回的。它的分詞應該是正向最大值的分詞方法,它沒有對方向再進行一次分詞和索引,索引無法查詢到。這個可能會被大家所忽略掉的。
㈤ sql server 索引 全文索引和聚類索引的區別
http://wenku..com/view/22ee60d376a20029bd642d75.html
看看文檔吧,有些東西需要耐心看下。
全文引擎使用全文索引中的信息來編譯可快速搜索表中的特定詞或片語的全文查詢。 全文索引將有關重要的詞及其位置的信息存儲在資料庫表的一列或多列中。 全文索引是一種特殊類型的基於標記的功能性索引,它是由 SQL Server 全文引擎生成和維護的。 生成全文索引的過程不同於生成其他類型的索引。 全文引擎並非基於特定行中存儲的值來構造 B 樹結構,而是基於要編制索引的文本中的各個標記來生成倒排、堆積且壓縮的索引結構。全文索引大小僅受運行 SQL Server 實例的計算機的可用內存資源限制。
從 SQL Server 2008 開始,全文索引與資料庫引擎集成在一起,而不是像 SQL Server 早期版本那樣位於文件系統中。對於新資料庫,全文目錄現在為不屬於任何文件組的虛擬對象;它僅是一個表示一組全文索引的邏輯概念。 然而,請注意,在升級 SQL Server 2005 資料庫(即包含數據文件的任意全文目錄)的過程中,將創建一個新文件組。
㈥ sql 全文搜索 怎麼分詞的
全文索引的核心理念是倒排索引(即反向索引),而最大的技術難點就在於分詞。
英文的分詞很簡單,直接按空格分詞即可。但中文不能這么干,主要原因有兩點:
中文詞與詞之間沒有空格
中文分詞結果存在歧義。例如:周立波/小人/傻逼 和 周立/波小/人傻逼,兩種分詞都說得通,只有結合上下文才知道哪一種對
因此,中文分詞比英文分詞要困難得多,學術界在這一領域已經研究了多年,並取得了很多研究成果,但目前,中文分詞的技術仍然很不完善。
回到全文搜索的話題,sql server自帶的中文分詞應該是基於正向最大匹配法的,說實話效果並不好。要求不高的話可以湊活用。除此之外,也有一些開源或商業的項目,例如Lucene(及其後續衍生),盤古等等,比sql server自帶的要強。但這些項目也有問題:一是分詞效果難稱完美,二是在資料庫中使用比較麻煩。
以上全部手打。有什麼問題請繼續問。
㈦ 關於MSSQL 全文索引 某些詞特別慢的問題
1. 執行計劃中明明有使用到索引,為什麼執行還是這么慢?
2. 執行計劃中顯示掃描行數為 644,為什麼 slow log 中顯示 100 多萬行?
a. 我們先看執行計劃,選擇的索引 「INDX_BIOM_ELOCK_TASK3(TASK_ID)」。結合 sql 來看,因為有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能會更差,優化器選擇這個索引避免了排序。
那為什麼不選 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很簡單,TASK_DATE 欄位區分度太低了,走這個索引需要掃描的行數很大,而且還要進行額外的排序,優化器綜合判斷代價更大,所以就不選這個索引了。不過如果我們強制選擇這個索引缺純(用 force index 語法),會看到 SQL 執行速度更快少於 10s,那是因為優化器基於代價的原則並不等價於執行速度的快慢;
b. 再看執行計劃中的 type:index,"index" 代表 「全索引掃描」,其實和全表掃描差不多,只是掃描的時候是按照索引次序進行而不是行,主要優點就是避免了排序,但是開銷仍然非常大。
Extra:Using where 也意味著掃描完索引後還需要回表進行篩選。一般來說,鄭數得保證 type 至少達到 range 級別,最好能達到 ref。
在第 2 點中提到的「慢日誌記錄Rows_examined: 1161559,看起來是全表掃描」,這里更正為「全索引掃描」,掃描行數確實等於表的行數;
c. 關於伏叢咐執行計劃中:「rows:644」,其實這個只是估算值,並不準確,我們分析慢 SQL 時判斷准確的掃描行數應該以 slow log 中的 Rows_examined 為准。
4. 優化建議:添加組合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
優化過程:
TASK_DATE 欄位存在索引,但是選擇度很低,優化器不會走這個索引,建議後續可以刪除這個索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在這個 sql 中 REL_DEVID 欄位從命名上看選擇度較高,通過下面 sql 來檢驗確實如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由於有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 組合選擇度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在測試環境添加 REL_DEVID,TASK_ID 組合索引,測試 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引後執行計劃:
這里還要注意一點「隱式轉換」:REL_DEVID 欄位數據類型為 varchar,需要在 sql 中加引號:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
執行時間從 10s+ 降到 毫秒級別:
1 row in set (0.00 sec)
結論
一個典型的 order by 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。