作者:溫安適
來源:my.oschina.net/floor/blog/4960148
引言
某個忙(mo)碌(yu)的下午,旁邊的劉哥(老江湖,從業5年+)突然發出了一聲嘆息:“哎,mysql 出bug了,有索引不走”,
作為一個熱心的人,我立即說到:“是不是,對索引欄位做了函式操作”,
劉哥沉思了2秒,略有玩味的小眼神看了看我,慢慢說道:“溫兄,常規的情況,對索引欄位做函式操作,或者 字串與數字比較造成的隱式轉換,這次的SQL都不涉及”,
我一聽頓時來了興趣,略帶興奮的跟劉哥說:“劉哥,您發SQL,我也研究下”,
劉哥略有無奈的看了看我后,依舊把SQL發給了我:
SELECT
*
FROM
oc_order oo
JOIN orders_detail od ON oo.order_id = od.order_id
不過須臾(近20分鐘),我便查明了原因,裝作大師的模樣,一字一句的說到:”這是,字符集隱式轉換問題”
劉哥聽后,百度了下,直拍大腿,“對對,怎么把這個給忘了”,
定位問題
1.首先執行explain,查看執行計劃
explain
SELECT
*
FROM
oc_order oo
JOIN orders_detail od ON oo.order_id = od.order_id

確實被驅動表orders_detail 沒走索引
第一個表就是驅動表,后邊的都是被驅動表,會從驅動板取出資料作為引數,到被驅動表查詢匹配的記錄,
2. 查看被驅動表的索引
SHOW INDEX FROM test.orders_detail;

3.查看欄位字符集
SELECT
COLUMN_NAME,
character_set_name,
collation_name
FROM
INformation_schema.`COLUMNS`
WHERE
TABLE_NAME = 'oc_order'
AND COLUMN_NAME = 'order_id';

SELECT
COLUMN_NAME,
character_set_name,
collation_name
FROM
INformation_schema.`COLUMNS`
WHERE
TABLE_NAME = 'orders_detail'
AND COLUMN_NAME = 'order_id';

Mysql字符集說明
utf8m4是utf8超集,utf8,與utf8mb4會比較,utf8會轉換為utf8mb4,
驗證
調整SQL陳述句,將oc_orders的order_id強制轉換為utf8,
explain
SELECT
*
FROM
oc_order oo
JOIN orders_detail od ON CONVERT ( oo.order_id USING UTF8 ) = od.order_id

查看執行計劃,確實走了索引
解決方式
1、調整SQL陳述句
SELECT
*
FROM
oc_order oo
JOIN orders_detail od ON CONVERT ( oo.order_id USING UTF8 ) = od.order_id
2、調整字符集一致,建議
總結
可能不走索引的 3 種情況:
- 對索引欄位做函式操作
- 隱式型別轉換,字串與數字比較,字串會轉換為數字
- 隱式字符集轉換,utf8m4是utf8超集,utf8,與utf8mb4會比較,utf8會轉換為utf8mb4.
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2021最新版)
2.終于靠開源專案弄到 IntelliJ IDEA 激活碼了,真香!
3.阿里 Mock 工具正式開源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式發布,全新顛覆性版本!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/288894.html
標籤:其他
上一篇:Python基礎之入門
