2013-07-16 54 views
2

我知道如何添加一個全文索引,做基本的布爾搜索...自動檢查全文索引,如果不存在,創建一個?

ALTER TABLE products ADD FULLTEXT KEY myIndex (model, description); 
SELECT * 
FROM products 
WHERE MATCH(model, description) AGAINST('myKeyword' in boolean mode); 

不過,我想知道是否有可能做這樣的事情......

我想我的SQL語句檢查「myIndex」存在,如果沒有它應該自動抓取現有的列名,並添加一個全文索引(注意在地方列名的*):

ALTER TABLE products ADD FULLTEXT KEY myIndex (*); 

另外,搜索索引的時候,我可以再自動抓取列名,而不是h AVING手動輸入(再次注意到的地方列名的*)...

SELECT * 
FROM products 
WHERE MATCH(*) AGAINST('myKeyword' in boolean mode); 

我不知道正確的語法,但這樣的事情可能嗎?我一直在谷歌搜索幾個小時,並無法找到答案。我知道我可以讓PHP生成我需要的SQL,但我想知道這是否可以嚴格使用SQL?

謝謝!

+0

Bill Karwin的這個答案將是解決問題的方法。但是,如果我理解你的問題,你正試圖找到一種動態索引數據庫的方式,這真的不是一個好主意。 – Namphibian

+0

在我構建的特定Web應用程序的情況下動態索引數據庫將會非常有用:)動態索引有什麼缺點? –

+0

查看我的回答下面@jerseymilker – Namphibian

回答

4

根據您的評論,您希望動態索引數據庫。這通常不是一個好主意。指數雙向切入這是一把雙刃劍。讓我解釋。

所以基本上索引是磁盤上的一個數據結構,它包含所有要索引的值。例如,假設您有一個包含10列的1000行表,並且索引1列,則此新索引也將包含1000個條目。它將包含該列的所有行值。然後將該索引寫入磁盤,以便讀取它。

下一次插入新行時,它必須插入到表和索引中。更新索引列時,必須更新表和索引。從我在你的問題中可以看到的,你想動態索引幾列。

因此可以說,你有一個相當大的表,其中有10000萬行和3列,並且你需要將它們索引爲需要索引的30000000個值。從本質上講,當你動態地創建這個索引時,服務器會在索引表時嚴重緩慢。同樣,一旦它完成你的插入將會更慢,更新索引列會更慢。一般經驗法則指數加快讀取速度並減慢插入速度。

現在只是爲了增加一點複雜性。您無法保證MySQL將使用新創建的索引。 MySQL使用內部統計信息來決定使用哪個索引。雖然在你的情況下,這可能不是一個問題,因爲你正在使用全文索引。你可以在MySQL中強制使用索引,但這也不是最佳的方法。

如果我可以提出建議,請不要這樣優化。您正在嘗試採用一種非常普遍的優化方法,即在所有地方應用索引。而是啓用慢查詢日誌並確定查詢運行緩慢。然後將這些查詢與解釋說明一起使用,以確定如何優化該情況。您將以較少的索引結束,並獲得良好的讀寫速度平衡。

我希望這一切都有一點意義。

+0

沒有道理,謝謝你的回覆。我明白你的意思是速度。但是,我正在構建一個CMS,其中我的客戶正在使用我的應用程序構建表結構。 CMS需要全文搜索,所以我希望索引在客戶端將結構添加到結構時自動發生。由於小型數據庫(最多500行),等待時間不應該成爲問題。也就是說,我想這樣做。如果我有機會在更大的數據庫上工作,我不想要速度問題。你會如何建議我設置索引,因爲用戶使用我的CMS添加字段?謝謝,我感謝你的時間! –

+1

主要建議,如果它不破解不修復它。基本上在需要的地方添加索引。您可以通過啓用慢速查詢日誌,然後通過在MySQL中使用EXPLAIN命令來查看這些查詢來了解如何優化它們。 – Namphibian

+0

好的,非常感謝! –

2

您可以檢查全文索引是否存在這樣的:

SELECT DISTINCT index_name 
FROM INFORMATION_SCHEMA.STATISTICS 
WHERE (table_schema, table_name) = ('mydatabase', 'products') 
    AND index_type = 'FULLTEXT'; 

你可以列在該指數是這樣的:

SELECT column_name 
FROM INFORMATION_SCHEMA.STATISTICS 
WHERE (table_schema, table_name) = ('mydatabase', 'products') 
    AND index_type = 'FULLTEXT' 
ORDER BY seq_in_index; 

不能使用MATCH(*)。這些列必須拼寫出來,您必須命名所有索引中的列,並且您必須按照您在定義索引時的相同順序命名它們。


我也應該注意到,對INFORMATION_SCHEMA一些查詢似乎慢,因爲InnoDB樣品表和索引通過讀取硬盤的隨機頁面。也就是說,讀取元數據會導致I/O。你可以用SET GLOBAL innodb_stats_on_metadata=0來緩解這個問題。另請參閱http://www.mysqlperformanceblog.com/2011/12/23/solving-information_schema-slowness/

+0

非常感謝比爾。明天早上我會玩這個! –

+0

如果'myIndex'全文索引已經存在,並且我在表結構中添加一個新列,是否可以將該新列添加到現有'myIndex'?或者我需要'改變表產品下降索引myIndex;',然後重新添加索引? –

+0

如果要添加列,則需要刪除索引並重新添加索引。 –

相關問題