1. 程式人生 > >關於 mysql 中 find_in_set 與 like 查詢的一些思考

關於 mysql 中 find_in_set 與 like 查詢的一些思考

前段時間專案中,使用到了mysql中的find_in_set 查詢,因為原先沒有使用過此方法,故進行了些許研究。

如mysql官方文件所說,find_in_set (str ,  strlist) 函式,查詢欄位(strlist)中包含 str 的結果,return 為 符合的結果 或者  null。舉例如下:

select * from  (select 1,2,3,'1,2,3' as strlist) as table1 where find_in_set('1',strlist);
返回如下:

另外一種情況:

select * from  (select 1,2,3,'1,2,3' as strlist) as table1 where find_in_set('0',strlist);
結果如下:


經過測試,已經可以看到使用like查詢是可以獲取到同樣結果的。而mysql中也有這樣的解釋:find_in_set 是精確匹配,欄位值以英文 ‘,’ 分隔,而like 是廣泛的模糊查詢,欄位中無需使用分隔符。可以說,兩者使用的情景不一樣,不過,看到這突然想到兩者的查詢方式是有何區別呢?於是使用真實的表進行了一下測試:

因find_in_set檢測的欄位需要使用英文逗號分隔,所以建立sql如下:

SELECT id FROM `consumer` WHERE find_in_set('hoftime',company);      
SELECT id FROM `consumer` WHERE company like ',hoftime,';
結果如下:



由上圖可看到,取出的結果集是有相同部分的,原因很簡單,like 查詢沒有使用萬用字元,而資料儲存是無序的,所以單純使用like查詢是隻能獲取單純的資料,find_in_set 會全域性精確匹配。那麼這就有了另外一個想法,那就是,find_in_set 以及 like ‘%%’ 兩者那一個比較優質呢?使用explain觀察sql執行順序,以上面的sql為基礎,修改查詢新增索引的欄位,測試如下:

explain SELECT id FROM `consumer` WHERE find_in_set('13888888888',mobile);

explain SELECT id FROM `consumer` WHERE mobile like ',13888888888,';

新增一個等同於第一條的sql,即like'%%'方式(結果與find_in_set一致):
explain SELECT id FROM `consumer` WHERE mobile like '%,13888888888,%';


由此可以看出,查詢結果一致的情況下,或者必須使用like‘%%’的情況下,二者任選其一即可,這個作用場景適合欄位中以英文逗號分隔的查詢語句。如果沒有逗號分隔,雖然都可以獲取到同樣的資料,但那樣的話,使用like查詢會更友好一些,畢竟like'str ',like'str%' 等都能夠使用索引,而同樣使用find_in_set 即使能夠獲取到想要的資料,成本也太高了。