索引無法應用的情況,隱式型別轉換,隱式字元編碼轉換

2021-09-25 13:49:48 字數 1989 閱讀 2713

條件字段函式操作

select count(*) from test where month(modified)=7;
如果對字段做了函式計算,就用不上索引了,這是 mysql 的規定。

對索引欄位做函式操作,可能會破壞索引值的有序性,因此優化器就決定放棄走樹搜尋功能。

mysql 無法再使用索引快速定位功能,而只能使用全索引掃瞄。

隱式型別轉換

select * from test where tradeid=110717;
tradeid 的字段型別是 varchar(32),而輸入的引數卻是整型,所以需要做型別轉換。此時就會需要走全表掃瞄,用不上索引。因為mysql 中,字串和數字做比較的話,是將字串轉換成數字。所以語句會變成下面這樣,相當於給了索引上加了函式。

select * from test where  cast(tradid as signed int) = 110717;
select * from test where id="83126";
這個情況就不會有影響,因為右側字串會轉變為整型。索引上沒有函式。 

隱式字元編碼轉換

tradelog表的tradeid編碼是 utf8mb4                       trade_detail 表的tradeid編碼是 utf8

select d.* from tradelog l, trade_detail d where d.tradeid=l.tradeid and l.id=2;
因為這兩個表的字符集不同,乙個是 utf8,乙個是 utf8mb4,所以做表連線查詢的時候用不上關聯欄位的索引

mysql 內部的操作是,先把 utf8 字串轉成 utf8mb4 字符集,再做比較。

這個設定很好理解,utf8mb4 是 utf8 的超集。類似地,在程式語言裡面,做自動型別轉換的時候,為了避免資料在轉換過程中由於截斷導致資料錯誤,也都是「按資料長度增加的方向」進行轉換的。

連線過程中要求在被驅動表的索引欄位上加函式操作,是直接導致對被驅動表做全表掃瞄的原因。 

這裡tradelog是驅動表              trade_detail是被驅動表  所以轉換成下面這個狀態

select * from trade_detail where tradeid=$l2.tradeid.value; 

select * from trade_detail where convert(traideid using utf8mb4)=$l2.tradeid.value;

如果換成下面這個sql就可以用上索引了,因為不需要轉換了  驅動表變成了trade_detail   tradelog是被驅動表 

select l.operator from tradelog l , trade_detail d where d.tradeid=l.tradeid and d.id=4;
還有個有趣的情況

`b` varchar(10)  有 100 萬行資料,其中有 10 萬行資料的 b 的值是』1234567890』

select * from table_a where b='1234567890abcd';
這條 sql 語句的執行很慢,流程是這樣的:

在傳給引擎執行的時候,做了字元截斷。因為引擎裡面這個行只定義了長度是 10,所以只截了前 10 個位元組,就是』1234567890』進去做匹配;

這樣滿足條件的資料有 10 萬行;

因為是 select *, 所以要做 10 萬次回表;

但是每次回表以後查出整行,到 server 層一判斷,b 的值都不是』1234567890abcd』;

返回結果是空。

發生隱式型別轉換的典型情況

1.在混合型別的算術表示式中 最寬的資料型別成為目標轉換型別,這也被稱為算術轉換,例如 int ival 3 double dval 3.14159 ival被提公升為double型別 3.0 ival dval 2.用一種型別的表示式複製給另一種型別的物件 在這種情況下目標轉換型別是被賦值給物件的...

隱式型別轉換

c 本身對內建型別定義了各種隱式的型別轉換,這種內建的型別轉換在可能導致精度 丟失的情況下編譯器會發出警告,但當我們定義自己的型別時,提供各種隱式轉換往往 是弊大於利的 至少在我編寫過的 中很少用到 隱式的型別轉換可分為 其它型別到本型別,本型別到其它型別兩種.第一種通過單變數 可呼叫之建構函式進行...

隱式型別轉換

c語言中有以下四種情況會進行隱式轉換 1 算術運算子中,低型別轉換為高型別。2 賦值表示式中,右邊表示式的值自動隱式轉換為左邊變數的型別,並賦值。3 函式呼叫傳遞引數時,系統將實參轉換為形參的型別後,賦給形參。4 函式有返回值是,系統將表達值型別轉換為返回值型別。進行算術運算時,不同型別的數必須轉換...