[MySQL]FIND_IN_SET

在一些狀況下,資料庫的資料可能存成以下這樣

name	category
Book1	1,2,3
Book2	1,3
Book3	1,8,10
Book4	2,9
Book5	1,9,11
Book6	9,25
Book7	9,12

如果要找出有 9 這個狀態的資料,可以直接在query中使用FIND_IN_SET這個函式

-- category 為欄位名稱
SELECT * FROM `table` WHERE FIND_IN_SET('9',category);

效能問題
但FIND_IN_SET這樣的做法,在資料量很大的時候非常有問題。原因是使用FIND_IN_SET並不會使用到index,所以會造成full table scan
要解決這個問題必須換個方法:

1.先把category GROUP BY 出來(縮小範圍)

SELECT * FROM `find_category` GROUP BY `category`;

2.針對 GROUP BY 的結果做FIND_IN_SET(確認結果)

SELECT * FROM (SELECT * FROM `find_category` GROUP BY `category`) as T WHERE FIND_IN_SET('9',T.category);

3.再用確認的結果去搜尋

SELECT * FROM `find_category` WHERE `category` IN ('1,9,11','2,9','9,12','9,25');

搜尋問題
另外在進行條件搜尋時,記得使用string

-- 結果只有 1
SELECT * FROM `find_category` WHERE `category` = '1';

如果是使用數字的話,除了搜尋不會用到index之外,出來的結果也會有問題

-- "1,2,3", "1", "1,8,10", "1,9,11"都會被搜出來
SELECT * FROM `find_category` WHERE `category` = 1;

[OS]The Silver Searcher (ag command)

[Go]Go lang安裝