[英]Big MySQL table, REPLACE -> very slow query
我的MyISAM數據庫中有一個包含1760萬行的表。
我想在其中搜索商品編號,但結果不能依賴於點,逗號和其他特殊字符。
我正在使用這樣的查詢:
SELECT * FROM `table`
WHERE
replace(replace(replace( replace( `haystack` , ' ', '' ),
'/', '' ), '-', '' ), '.', '' )
LIKE 'needle'
這種方法非常慢。 table
在haystack
上有一個索引,但EXPLAIN
顯示查詢不能使用該索引,這意味着查詢必須在3.8秒內掃描1760萬行。
查詢在頁面中運行多次(10-15倍),因此頁面加載速度極慢。
我該怎么辦? 在查詢中使用replace是一個壞主意嗎?
您可以嘗試在列上使用LENGTH
,不確定是否會帶來更好的效果。 另外,使用LIKE
請使用%
SELECT * FROM `table`
WHERE
haystack LIKE 'needle%' AND
LENGTH(haystack) - LENGTH(REPLACE(haystack,'/','')) = 0 AND
LENGTH(haystack) - LENGTH(REPLACE(haystack,'-','')) = 0 AND
LENGTH(haystack) - LENGTH(REPLACE(haystack,'.','')) = 0;
如果大海撈針正好是針,那就這樣做
SELECT * FROM `table`
WHERE
haystack='needle';
將功能應用於列是“不好的”做法,因為它將強制掃描列。
也許這是一個更好的方法:
SELECT list
, of
, relevant
, columns
, only
FROM your_table
WHERE haystack LIKE 'two[ /-.]needles'
在這種情況下,我們正在搜索“兩針”,其中單詞之間的空格可以是方括號內的任何字符,即“兩針”,“兩針”,“兩針”或“ two.needles” ”。
當您對表中的實際數據進行替換時,MySQL無法使用索引,因為它沒有替換結果的任何索引數據,而替換結果需要與needle
比較。
也就是說,如果您的替換設置是靜態的,則最好對數據進行非規范化並添加一個新的列,例如haystack_search
,其中包含應用了所有替換的數據。 可以在INSERT
或UPDATE
期間填充此列。 然后可以有效地使用此列上的索引。
請注意,您可能希望在LIKE
查詢中使用%
,否則它實際上與普通的相等比較相同。 現在,如果您使用%needle%
類的搜索字詞(即帶有變量start),則MySQL再次無法使用索引並退回到表掃描,因為它只有在看到固定的開始時才可以使用索引。搜索字詞,例如needle%
。
因此,最后,您可能最終不得不調整數據庫引擎,以便它可以將表保存在內存中。 MyISAM表(或MySQL 5.6及更高版本,以及InnoDB表)的另一種選擇是對數據使用全文索引,這再次允許相當有效的搜索。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.