接著前一天的資料
user
id | phone | name | created_at |
---|---|---|---|
9 | 0944555666 | user9 | 2023-10-30 13:45:25 |
3 | 0912345678 | user3 | 2023-12-05 18:35:20 |
1 | 0912333555 | user1 | 2024-01-22 09:10:45 |
8 | 0933444555 | user8 | 2024-03-28 11:15:50 |
7 | 0922111333 | user7 | 2024-04-12 17:22:33 |
10 | 0955666777 | user10 | 2024-05-18 22:50:12 |
6 | 0912999888 | user6 | 2024-06-30 08:00:10 |
11 | 0966777888 | user11 | 2024-07-05 07:35:40 |
5 | 0908070605 | user5 | 2024-08-15 14:25:00 |
在這次的資料中,如果我們這次的條件為
select * from user where created_at >= '2024-03-01 00:00:00' and created_at < '2024-07-01 00:00:00' and phone like '091%'
如果這時我們沒有建立index
需要確認的資料有9行
但如果有針對created_at
建立index,這時,就可以直接將範圍縮小到
user
id | phone | name | created_at |
---|---|---|---|
8 | 0933444555 | user8 | 2024-03-28 11:15:50 |
7 | 0922111333 | user7 | 2024-04-12 17:22:33 |
10 | 0955666777 | user10 | 2024-05-18 22:50:12 |
6 | 0912999888 | user6 | 2024-06-30 08:00:10 |
就只剩下4行,這時無論要做什麼樣的搜尋,一定就會變的更快
接著上面的資料集以及搜尋query
select * from user where created_at >= '2024-03-01 00:00:00' and created_at < '2024-07-01 00:00:00' and phone like '091%'
這時如果我們需要優化搜尋速度,很明顯的需要針對created_at
以及phone
建立index
但這時
CREATE INDEX user_index1 ON user (created_at, phone);
跟
CREATE INDEX user_index2 ON user (phone, created_at);
這兩個語法是完全不相同的
index1
created_at | phone |
---|---|
2023-10-30 13:45:25 | 0944555666 |
2023-12-05 18:35:20 | 0912345678 |
2024-01-22 09:10:45 | 0912333555 |
2024-03-28 11:15:50 | 0933444555 |
2024-04-12 17:22:33 | 0922111333 |
2024-05-18 22:50:12 | 0955666777 |
2024-06-30 08:00:10 | 0912999888 |
2024-07-05 07:35:40 | 0966777888 |
2024-08-15 14:25:00 | 0908070605 |
index2
created_at | phone |
---|---|
2024-08-15 14:25:00 | 0908070605 |
2024-01-22 09:10:45 | 0912333555 |
2023-12-05 18:35:20 | 0912345678 |
2024-06-30 08:00:10 | 0912999888 |
2024-04-12 17:22:33 | 0922111333 |
2024-03-28 11:15:50 | 0933444555 |
2023-10-30 13:45:25 | 0944555666 |
2024-05-18 22:50:12 | 0955666777 |
2024-07-05 07:35:40 | 0966777888 |
可以看到,如果此時我們只有建立index2,那這時資料庫一開始看到created_at的時候,因為index一開始沒有依照時間排,所以就會去原始的表去塞選需要的資料,最後才去看到phone有開頭的,所以總共找尋的資料是9筆
但如果我們有index1,這時候一看到created_at,就可以先看index內的資料,再來又可以繼續看著index把指定的範圍找出來
所以在query的時候,where的順序很重要
另外,在where的時候,如果是equal跟like同時出現,equal要盡量往前放,因為這樣才能有效的利用已經建立好的index
Ref:
https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning