程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 改善MySQL上16進制標識符性能的5種方法

改善MySQL上16進制標識符性能的5種方法

編輯:MySQL綜合教程

這裡講得是如何在使用16進制大數據的情況下保持好的性能,主要講的是MySQL數據庫,對其他數據庫應該也起作用。

一、小心你的字符編碼

看一下下面這個SQL語句:

mysql> explain select * from t where id = ’0cc175b9c0f1b6a831c399e269772661′G
***************************              1. row

 ***************************
id: 1
select_type: SIMPLE
table: t
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 98
ref: const
rows: 1
Extra: Using index

為什麼索引是98byte?簡單,因為我們用的是UTF-8:

CREATE TABLE `t` (
`id` varchar(32) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

沒有必要用UTF-8存儲16進制數據,采用UTF-8存儲16進制數據不會增加磁盤空間的占用,但是當你使用排序(order by)、統計(group by)、隱式臨時表(MySQL查詢時自建的臨時表)等的時候,需要耗費多達3倍的內存和硬盤空間,至少在MySQL上是這樣的。

二、使用固定長度,不要有空值

可以看到上面那個表采用的是varchar字段,我們都知道varchar是一個變長字段,如果你確認所有的數據都一樣長(比如像md5()出來的,都是32個字節),最好使用char()定長字段,另外就是如果字段中不可能有空值,最好指定為not null

三、使用二進制數據存儲

實際上,你並不需要存儲字符串,16進制字符串不過是數字的另一種表現形式,直接保存數字。比如:00000000000000000000000000002E2A是什麼呢?這正是16進制數字11818,使用一個4字節(或者更少)的整型代替一個32字節的字符存儲更好。

問題是MySQL沒有合適的類型來存儲這麼大的數字,它們比BIGINT還要大很多,不過MySQL允許我們存儲到BINARY字段,數據更緊湊比較起來更快速,可以使用HEX()和UNHEX()來轉換格式,或者16進制操作符’x’

mysql> select x’7861707262′;
+—————+
| x’7861707262′ |
+—————+
| xaprb         |
+—————+

用BINARY(16)代替varchar(32)之後:

explain select * from t where id = x’0cc175b9c0f1b6a831c399e269772661′G
***************************           1. row

***************************
id: 1
select_type: SIMPLE
table: t
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 16
ref: const
rows: 1
Extra: Using index

索引長度變成16字節了(對比原來98字節),減小了不少,如果你使用的是UUID(),存入之前先用replace()把”-”題換掉。

四、使用前綴索引

很多時候,我們不需要索引全部字段,索引字段的前8~10個字符就可以了,如果你當前存儲的是字符串,這很有用,不用轉換成BINARY,只是改變索引策略而已。

你可以通過類似下面的SQL語句判斷合適的前綴索引個數:

mysql> select count(distinct id), count(distinct left(id, 8)), count(distinct left(id, 9)) from tG
*************************** 1. row ***************************
count(distinct id): 2
count(distinct left(id, 8)): 2
count(distinct left(id, 9)): 2

找一個差不多行就可以,不一定要索引“唯一”。

五、創建hash索引

直接上代碼,不用多余的解釋:

mysql> alter table t add crc int unsigned not null, add key(crc);
mysql> update t set crc=crc32(id);
mysql> explain select * from t use index(crc) where id = ’0cc175b9c0f1b6a831c399e269772661′ and crc=crc32(’0cc175b9c0f1b6a831c399e269772661′)G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t
type: ref
possible_keys: crc
key: crc
key_len: 4
ref: const
rows: 1
Extra: Using where

使用crc32()獲取到字符串的校驗值,一般這樣的碰撞概率不會太大,索引數字比索引字符不知道要快多少,極力推薦,不僅僅適用16進制字符,任意字符也適合:

mysql> select crc32(‘good good study, and day day up!’);
+——————————————-+
| crc32(‘good good study, and day day up!’) |
+——————————————-+
|                                2265998365 |
+——————————————-+
1 row in set (0.00 sec)

總結:

16進制標識符讓表和索引的變大,降低比較和查找的速度,建議非不得已不要使用,如果非要使用,希望上面的五條建議對你有用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved