2016-05-04 51 views
0

我有多個CURL腳本從許多內部公司網站收集數據到共享數據庫。每個腳本被稱爲「實例」。數據以記錄的形式添加到數據庫中。每條記錄都有多個「字段」,它們是鍵 - >值對。由於每條記錄的關鍵字都是動態的,並且可以是任何東西(即使在同一個實例中),它們也不會被硬編碼到MySQL表中。MySQL與MATCH查詢和反對掛起

所以有這些表:

  1. 記錄 - 包含記錄列表,用
  2. record_fields實例的每個相關 - 包含一個記錄相關的字段列表
  3. record_fields_labels - 基本上是一個標籤列表。這存儲在數據庫中以節省空間(即,而不是record_fields有成千上萬的字段,其標籤爲「文章日期」),它們將具有編號8,這是record_labels上具有「文章日期「作爲它的價值)。

record_fields和record_fields_labels與關於「內容」(在包含實際數據的record_fields列)和「標記」(在record_fields_labels列具有標籤名稱)一個FULLTEXT索引二者MyISAM表。

該數據庫擁有數百萬的記錄 - 每個多次記錄中的字段... 當實例運行的數量來檢查記錄是否已在數據庫中存在,他們做下面的SQL查詢:

SELECT r.id FROM records r INNER JOIN record_fields rf ON rf.record_id=r.id INNER JOIN record_fields_labels as rfl ON rf.label=rfl.id WHERE r.instance IN (120) AND MATCH (rf.content) AGAINST ('"http://xxxx.xxxx/xxx.xxx.xxx"' IN BOOLEAN MODE) AND MATCH (rfl.label) AGAINST ('"Article URL"' IN BOOLEAN MODE) GROUP BY r.id 

在這個例子中,http://xxxx.xxxx/xxx.xxx.xxx是一個腳本會檢查系統中是否存在的文章的URL。

TL; DR

問題是這樣的:當數據庫是巨大的(即百萬記錄/記錄的字段) - 上面的查詢簡單地掛斷了電話。查詢會運行,甚至幾個小時,沒有明顯的原因。這個查詢用於搜索收集到的數據中的項目,並且似乎可以工作(或直到最近纔開始工作)。

我只想讓它顯示這樣的記錄是否存在。 它似乎不是一個索引問題,但是與MATCH AGAINST特別有關。我更願意避免爲所有內容(除了全文索引)增加索引以節省空間。

有誰知道是什麼原因導致了這個掛斷問題?

感謝

+0

您是否在SQL上運行了'EXPLAIN'來查看引擎如何運行查詢? – syck

+0

而且:通常,智能構建的索引是找到或證明其存在的最有效的方法。那就是它的用途。 – syck

回答

0

看起來像您使用全文索引,你不必,尤其是對您的標籤。如果這些都很簡單並且定義良好,那麼正常的索引就可以。如果您需要區分「文章日期」和「博客日期」,例如對於內容類型使用一個字段,對數據類型使用一個字段。

當您使用MATCH AGAINST ... IN BOOLEAN MODE搜索短語時,您實際上是按相同的順序搜索相同的單詞,而不是完整的字符串。看到DOCS

在你的領域的內容搜索「http://xxxx.yyy/www.zzz.mmm」實際上將匹配「這裏的一些內容的HTTP,XXXX。YYY WWW!ZZZ嗯?是的,請,更多的內容」,而且是假設你的全文最小單詞長度爲3或減。對於性能和邏輯,這不是正確的索引。

我會認真考慮改變你的數據結構,以便你不把全文索引放在網址和標籤上。這可能會比避免使用普通索引節省更多的空間。