MySQL字符集不一致導致查詢SQL性能問題



今天做了一個MySQL數據庫中的SQL優化。

結論是關聯字段字符集不同,導致索引不可用。

查詢的SQL如下:

select 
   `Alias`.`Grade`, 
   `Alias`.`id`, 
   `Alias`.`Cust_Name`, 
   `Alias`.`Agent_Code1`
 from `database_name1`.`TAB1` as `Alias`
 where (
   `Alias`.`Agent_Code1` = '1090300496329'
   and `Alias`.`id` in (
     select `database_name1`.`TAB2`.`B`
     from `database_name1`.`TAB2`
       join `database_name1`.`TAB3` as `T1`
       on `T1`.`id` = `database_name1`.`TAB2`.`A`
     where (
       `T1`.`Cust_Type` in (
         '1200001', '1200002'
       )
       and `T1`.`id` in (
         select `database_name1`.`TAB4`.`B`
         from `database_name1`.`TAB4`
           join `database_name1`.`TAB5` as `T2`
           on `T2`.`id` = `database_name1`.`TAB4`.`A`
         where `T2`.`Cont_Meth_Tp_Cd` = '1220001'
       )
     )
   )
 )
 order by 
   `Alias`.`Cust_Name` asc, 
   `Alias`.`id` asc
 limit 11
 offset 0

  

SQL的執行計划如下 :

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: Alias
   partitions: NULL
         type: ref
possible_keys: PRIMARY
      key_len: 203
          ref: const
         rows: 894
     filtered: 100.00
        Extra: Using index condition
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: TAB2
   partitions: NULL
         type: ref
possible_keys: TAB2_IDX
          key: TAB2_IDX
      key_len: 103
          ref: database_name1.Alias.id
         rows: 1
     filtered: 100.00
        Extra: Using where; Using index
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: HDL_ADD_CUSTOMER_Alias
   partitions: NULL
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 77
          ref: func
         rows: 1
     filtered: 55.42
        Extra: Using where
*************************** 4. row ***************************
           id: 1
  select_type: SIMPLE
        table: TAB4
   partitions: NULL
         type: index
possible_keys: NULL
          key: TAB4_IDX
      key_len: 206
          ref: NULL
         rows: 5852807
     filtered: 100.00
        Extra: Using where; Using index
*************************** 5. row ***************************
           id: 1
  select_type: SIMPLE
        table: T2
   partitions: NULL
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 142
          ref: database_name1.TAB5.A
         rows: 1
     filtered: 50.00
        Extra: Using where; FirstMatch(Alias)
5 rows in set, 1 warning (0.01 sec)

  

 

由於對MySQL執行計划不熟,看了半天也沒看出有啥問題。
但是第4行有一個地方引起我的注意了,possible_keys = NULL ,key = TAB4_IDX
字面理解:可能走的索引沒有,實際上走了索引。
實際上是沒有走索引范圍掃描。后來從MySQL Wordbench 的執行計划里找到了端倪。

在TAB4表上的關聯字段ID發生了隱式轉換,這個字段的字符集是 gbk的, 而t2.id 字符集是utf8 的;
結果導致轉換后,tab4上的索引沒法使用。發生了 block nested loops;
從索引中讀所有數據到內存。 index full scan ;

確認這段時間可以更新,把ID字段字符集都改成一致即可。

ALTER TABLE `database_name1`.`tab3` 
CHANGE COLUMN `id` `id` VARCHAR(25) CHARACTER SET 'gb18030' NOT NULL ;

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM