MySQL優化索引及優化漢字模糊查詢語句
阿新 • • 發佈:2019-01-03
利用MySQL這種關係型資料庫來做索引,的確有些勉強了,也只能看情況來說了,有些簡單的功能還是可以考慮的。
對於模糊查詢語句,最不利的情況是要like '%key%'這樣的查詢,但是如果是like 'key%'這種情況,那麼mysql的索引在些查詢方式上還是可以優化的。
網上常見的是ASCII的英文字元優化,如下:
- select corp_code, corp_corp from tb_Z_Corp where corp_code like'0008%';
舉個例子來看看問題的來源吧:
先看一下要試驗表的建立語句和結構,這是一個只包含股票程式碼和股票名稱的資料表,主鍵為股票程式碼:
-
mysql> show
- +-----------+-----------------------------------+
- | Table | CreateTable |
- +-----------+-----------------------------------+
- | tb_Z_Corp | CREATETABLE `tb_Z_Corp` (
- `corp_code` char(10) NOTNULL,
- `corp_corp` varchar(60) NOTNULL,
-
PRIMARYKEY (`corp_code`),
- KEY `idx_Z_Corp_corp_corp` (`corp_corp`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
- +-----------+-----------------------------------+
- mysql> desc tb_Z_Corp;
- +---------------+-------------+------+-----+---------+-------+
-
| Field | Type | Null | Key | Default | Extra |
- +---------------+-------------+------+-----+---------+-------+
- | corp_code | char(10) | NO | PRI | | |
- | corp_corp | varchar(60) | NO | MUL | | |
- +---------------+-------------+------+-----+---------+-------+
表裡面的資料舉例如下(股票程式碼和股票名稱):
- +-----------+--------------+
- | corp_code | corp_corp |
- +-----------+--------------+
- | 000800 | 一汽轎車 |
- | 000801 | 四川九洲 |
- | 000802 | 北京旅遊 |
- | 000803 | 金宇車城 |
- | 000805 | *ST炎黃 |
- | 000806 | 銀河科技 |
- | 000807 | 雲鋁股份 |
- | 000809 | 中匯醫藥 |
看一下要待優化的語句(一個英文、一個中文的):
- select corp_code, corp_corp from tb_Z_Corp where corp_code like'0008%';
- select corp_code, corp_corp from tb_Z_Corp where corp_corp like'江%';
對於第一個待優化的SQL語句來說,比較簡單,很多地方都介紹過怎樣優化:
- 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進位制編碼的字串,所以我們優化後的語句應該是這樣的:
- select corp_code, corp_corp from tb_Z_Corp where corp_corp >= '江'and corp_corp < CONCAT('江', x'EFBFBF');
這樣就達到了不用like語句比較表中的每一條記錄,而直接使用索引快速檢索。看,結果出來了:
- +-----------+--------------+
- | corp_code | corp_corp |
- +-----------+--------------+
- | 600750 | 江中藥業 |
- | 002226 | 江南化工 |
- | 601199 | 江南水務 |
- | 000519 | 江南紅箭 |
- | 600527 | 江南高纖 |
- | 002061 | 江山化工 |
- | 600389 | 江山股份 |
- | 600212 | 江泉實業 |
- | 002484 | 江海股份 |
- | 000816 | 江淮動力 |
- | 600418 | 江淮汽車 |
- | 002176 | 江特電機 |