mysql tinyint和char(1)性能对比
在數(shù)據(jù)庫(kù)設(shè)計(jì)的時(shí)候會(huì)遇到很多只需要0、1、2這種固定幾個(gè)值的狀態(tài)字段,基本上都建議設(shè)置為只占一字節(jié)的tinyint類(lèi)型,有些覺(jué)得char(1)是一樣,畢竟char(1)存儲(chǔ)數(shù)字和字母時(shí)一個(gè)字符也只是占一個(gè)字節(jié)
mysql是用c++寫(xiě)的,而在c++中字符類(lèi)型是存放對(duì)應(yīng)ascii碼的二進(jìn)制到存儲(chǔ)空間,而整型數(shù)字是直接存數(shù)字的二進(jìn)制,雖然最終都是二進(jìn)制存儲(chǔ),但是環(huán)節(jié)上有少許不同,同樣在msyql查找時(shí)也會(huì)有所不同,下圖摘自小白版c++教程《c++ primer plus》:
今天對(duì)tinyint和char(1)做了個(gè)簡(jiǎn)單測(cè)試,分表建兩個(gè)表t1、t2,結(jié)構(gòu)如下:
mysql> show create table t1\G
*************************** 1. row ***************************
? ? ? ?Table: t1
Create Table: CREATE TABLE `t1` (
? `_id` int(11) NOT NULL AUTO_INCREMENT,
? `id` tinyint(4) DEFAULT NULL,
? `title` text,
? PRIMARY KEY (`_id`),
? KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2400096 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t2\G
*************************** 1. row ***************************
? ? ? ?Table: t2
Create Table: CREATE TABLE `t2` (
? `_id` int(11) NOT NULL AUTO_INCREMENT,
? `id` char(1) DEFAULT NULL,
? `title` text,
? PRIMARY KEY (`_id`),
? KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2400096 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
兩個(gè)表唯一不同為id字段類(lèi)型,總數(shù)據(jù)量都為2400096,id只有0、1、2三個(gè),為了兩個(gè)表的數(shù)據(jù)一樣且磁盤(pán)上分布也一樣,降低IO對(duì)測(cè)試的影響,分別加載的數(shù)據(jù)如下:
mysql> select id,count(*) from t1 group by id;
+------+----------+
| id ? | count(*) |
+------+----------+
| ? ?0 | ?1199998 |
| ? ?1 | ?1199998 |
| ? ?2 | ? ? ? 99 |
+------+----------+
3 rows in set (0.55 sec)
mysql> select id,count(*) from t2 group by id;?
+------+----------+
| id ? | count(*) |
+------+----------+
| 0 ? ?| ?1199998 |
| 1 ? ?| ?1199998 |
| 2 ? ?| ? ? ? 99 |
+------+----------+
3 rows in set (0.77 sec)
查看執(zhí)行計(jì)劃:
mysql> explain select _id from test.t2 where id='1'; ? ? ? ? ? ? ? ? ? ? ?
+----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key ?| key_len | ref ? | rows ? ?| Extra ? ? ? ? ? ? ? ? ? ?|
+----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------+
| ?1 | SIMPLE ? ? ?| t2 ? ?| ref ?| id ? ? ? ? ? ?| id ? | 4 ? ? ? | const | 1170900 | Using where; Using index |
+----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------+
1 row in set (0.00 sec)
mysql> explain select _id from test.t1 where id=1;?
+----+-------------+-------+------+---------------+------+---------+-------+---------+-------------+
| id | select_type | table | type | possible_keys | key ?| key_len | ref ? | rows ? ?| Extra ? ? ? |
+----+-------------+-------+------+---------------+------+---------+-------+---------+-------------+
| ?1 | SIMPLE ? ? ?| t1 ? ?| ref ?| id ? ? ? ? ? ?| id ? | 2 ? ? ? | const | 1170601 | Using index |
+----+-------------+-------+------+---------------+------+---------+-------+---------+-------------+
1 row in set (0.00 sec)
兩個(gè)表都使用了id索引,再看看information_schema.tables的信息是否和之前理解的存儲(chǔ)字節(jié)大小是否有出入:
mysql> select DATA_LENGTH/1024/1024,INDEX_LENGTH/1024/1024,data_free from tables where table_name in ('t1','t2');
+-----------------------+------------------------+-----------+
| DATA_LENGTH/1024/1024 | INDEX_LENGTH/1024/1024 | data_free |
+-----------------------+------------------------+-----------+
| ? ? ? ? ?310.81250000 | ? ? ? ? ? ?27.56250000 | ? ? ? ? 0 |
| ? ? ? ? ?313.81250000 | ? ? ? ? ? ?29.56250000 | ? ? ? ? 0 |
+-----------------------+------------------------+-----------+
2 rows in set (0.00 sec)
兩個(gè)表大小相差不多,確認(rèn)char(1)和tinyint占字節(jié)數(shù)相同,現(xiàn)在直接看執(zhí)行時(shí)間:
mysql> show profiles;
+----------+------------+---------------------------------------------------------------+
| Query_ID | Duration ? | Query ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+----------+------------+---------------------------------------------------------------+
| ? ? ? ?1 | 0.60804275 | select count(*) from (select _id from test.t1 where id=1) a ? |
| ? ? ? ?2 | 0.59277575 | select count(*) from (select _id from test.t1 where id=1) a ? |
| ? ? ? ?3 | 0.60398000 | select count(*) from (select _id from test.t1 where id=1) a ? |
| ? ? ? ?4 | 0.69068025 | select count(*) from (select _id from test.t2 where id='1') a |
| ? ? ? ?5 | 0.69654200 | select count(*) from (select _id from test.t2 where id='1') a |
| ? ? ? ?6 | 0.67788800 | select count(*) from (select _id from test.t2 where id='1') a |
+----------+------------+---------------------------------------------------------------+
這樣就很明顯可以看出為char(1)字段的t2表查詢(xún)時(shí)消耗時(shí)間偏多,如果幾條幾百條的情況根本看不出char(1)和tinyint的差別,畢竟現(xiàn)在CPU的效率是非常高的,這里測(cè)試的利用了id=1的數(shù)據(jù),有1199998條,這樣就可以看出點(diǎn)差別了!!雖然效率差別不是很大,為了生產(chǎn)環(huán)境統(tǒng)一以及提升QPS還是使用短小的整型更好
轉(zhuǎn)載于:https://blog.51cto.com/xiaozhong991/1892569
總結(jié)
以上是生活随笔為你收集整理的mysql tinyint和char(1)性能对比的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。