關於 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 即使能夠獲取到想要的數據,成本也太高了。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章