1. 程式人生 > >MySQL優化索引及優化漢字模糊查詢語句

MySQL優化索引及優化漢字模糊查詢語句

利用MySQL這種關係型資料庫來做索引,的確有些勉強了,也只能看情況來說了,有些簡單的功能還是可以考慮的。

對於模糊查詢語句,最不利的情況是要like '%key%'這樣的查詢,但是如果是like 'key%'這種情況,那麼mysql的索引在些查詢方式上還是可以優化的。

網上常見的是ASCII的英文字元優化,如下:

  1. select corp_code, corp_corp from tb_Z_Corp where corp_code like'0008%';  

舉個例子來看看問題的來源吧:

先看一下要試驗表的建立語句和結構,這是一個只包含股票程式碼和股票名稱的資料表,主鍵為股票程式碼:

  1. mysql> show 
    createtable tb_Z_Corp;  
  2. +-----------+-----------------------------------+
  3. Table     | CreateTable                      |  
  4. +-----------+-----------------------------------+
  5. | tb_Z_Corp | CREATETABLE `tb_Z_Corp` (  
  6.   `corp_code` char(10) NOTNULL,  
  7.   `corp_corp` varchar(60) NOTNULL,  
  8.   PRIMARYKEY  (`corp_code`),  
  9.   KEY `idx_Z_Corp_corp_corp` (`corp_corp`)  
  10. ) ENGINE=MyISAM DEFAULT CHARSET=utf8            |   
  11. +-----------+-----------------------------------+
  12. mysql> desc tb_Z_Corp;  
  13. +---------------+-------------+------+-----+---------+-------+
  14. | Field         | Type        | Null | Key | Default | Extra |  
  15. +---------------+-------------+------+-----+---------+-------+
  16. | corp_code     | char(10)    | NO   | PRI |         |       |   
  17. | corp_corp     | varchar(60) | NO   | MUL |         |       |   
  18. +---------------+-------------+------+-----+---------+-------+

表裡面的資料舉例如下(股票程式碼和股票名稱):

  1. +-----------+--------------+
  2. | corp_code | corp_corp    |  
  3. +-----------+--------------+
  4. | 000800    | 一汽轎車     |   
  5. | 000801    | 四川九洲     |   
  6. | 000802    | 北京旅遊     |   
  7. | 000803    | 金宇車城     |   
  8. | 000805    | *ST炎黃      |   
  9. | 000806    | 銀河科技     |   
  10. | 000807    | 雲鋁股份     |   
  11. | 000809    | 中匯醫藥     |   

看一下要待優化的語句(一個英文、一個中文的):

  1. select corp_code, corp_corp from tb_Z_Corp where corp_code like'0008%';  
  2. select corp_code, corp_corp from tb_Z_Corp where corp_corp like'江%';  

對於第一個待優化的SQL語句來說,比較簡單,很地方都介紹過怎樣優化:

  1. select corp_code, corp_corp from tb_Z_Corp where corp_code >= '0008'and corp_code < '0009';  

而對於第二個是中文字元,馬上想到是加一個最大編碼的漢字,這裡資料庫儲存的是UTF-8格式儲存,而漢字的編碼為3位元組,所以按其最大編碼的規則應該是:
Unicode編碼是從U+0800到U+FFFF先標記一下這16位:“zzzzyyyy yyxxxxxx”;
然後把這16位對應到UTF-8的編碼:“1110zzzz 10yyyyyy 10xxxxxx”。
所以最大的3個位元組的編碼為“11101111 10111111 10111111”,也就是十六進位制的“EFBFBF”。
在MySQL中,用x'EFBFBF'表明這裡面是用16進位制編碼的字串,所以我們優化後的語句應該是這樣的:

  1. select corp_code, corp_corp from tb_Z_Corp where corp_corp >= '江'and corp_corp < CONCAT('江', x'EFBFBF');  

這樣就達到了不用like語句比較表中的每一條記錄,而直接使用索引快速檢索。看,結果出來了:

  1. +-----------+--------------+
  2. | corp_code | corp_corp    |  
  3. +-----------+--------------+
  4. | 600750    | 江中藥業     |   
  5. | 002226    | 江南化工     |   
  6. | 601199    | 江南水務     |   
  7. | 000519    | 江南紅箭     |   
  8. | 600527    | 江南高纖     |   
  9. | 002061    | 江山化工     |   
  10. | 600389    | 江山股份     |   
  11. | 600212    | 江泉實業     |   
  12. | 002484    | 江海股份     |   
  13. | 000816    | 江淮動力     |   
  14. | 600418    | 江淮汽車     |   
  15. | 002176    | 江特電機     |