MySQL - FIND_IN_SET
MySQL:8.0.26
MySQL 中的 FIND_IN_SET 函式是用來搜尋與 StringList
符合的字串。
用法上為:FIND_IN_SET(str, strList)
。
Basic Usage
先假設一個情境,假設資料庫中有數本書的資料,每本都帶有不同且多個 分類(Category)
,而分類是透過 StringList
表示。
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
這個函式。
SELECT * FROM `table` WHERE FIND_IN_SET('9', category);
Performance issue
不過,使用 FIND_IN_SET
時並不會利用到 Index
,因此每次的操作其實都是 Full table scan
,在資料量很大的時候就會有很嚴重的效能問題。
要解決這個問題可以透過降低資料分母的概念去調整:
Step 1. 先找出 table 中不重複的 category(降低分母)
SELECT DISTINCT category FROM table;
Step 2. 透過 sub query 針對第一步的結果做 FIND_IN_SET(確認結果)
SELECT * FROM (SELECT DISTINCT category FROM table) as T WHERE FIND_IN_SET('9', T.category);
Step 3. 再用確認的結果去搜尋(使用 Index)
SELECT * FROM table WHERE `category` IN ('1,9,11', '2,9', '9,12', '9,25');