根據英文的測試結論來看,Archive表比MyISAM表要小大約75%,比支持事務處理的InnoDB表小大約83%。當數據量非常大的時候Archive的插入性能表現會較MyISAM為佳。
Archive表的性能是否可能超過MyISAM?答案是肯定的。根據MySQL工程師的資料,當表內的數據達到1.5GB這個量級,CPU又比較快的時候,Archive表的執行性能就會超越MyISAM表。因為這個時候,CPU會取代I/O子系統成為性能瓶頸。別忘了Archive表比其他任何類型的表執行的物理I/O操作都要少。
較小的空間占用也能在你移植MySQL數據的時候發揮作用。當你需要把數據從一臺MySQL服務器轉移到另一臺的時候,Archive表可以方便地移植到新的MySQL環境,你只需將保存Archive表的底層文件復制過去就可以了。
本著懷疑一切的精神,本人進行了如下的測試:
①建立一個iplog的表:
mysql> create table iplog(id int auto_increment not null primary key,userid int,ip char(15),visit_time datetime) engine=innodb;
②使用python腳本插入50w數據:
#!/usr/bin/mysql
import MySQLdb
conn = MySQLdb.connect(host="localhost",user="root",passwd="asdf",db="test",unix_socket="/data/mysql_3306/mysql.sock")
cursor = conn.cursor()
for i in range(0,500000):
sql = "insert into iplog(userid,ip,visit_time) values(%s,'127.0.0.1',now())"%i
cursor.execute(sql)
cursor.close()
conn.commit()
conn.close()
③分別創建iplog對應的archive、InnoDB、MyISAM對應表格并插入數據
mysql> create table iplog_archive engine=archive as select * from iplog;
Query OK, 500000 rows affected (2.73 sec)
Records: 500000 Duplicates: 0 Warnings: 0
mysql> create table iplog_myisam engine=myisam as select * from iplog;
Query OK, 500000 rows affected (1.39 sec)
Records: 500000 Duplicates: 0 Warnings: 0
mysql> create table iplog_innodb engine=innodb as select * from iplog;
Query OK, 500000 rows affected (4.78 sec)
Records: 500000 Duplicates: 0 Warnings: 0
④比較它們的大小
mysql> select table_name,engine,ROUND(data_length/1024/1024,2) total_size_mb,table_rows from information_schema.tables
-> where table_schema = 'test' and table_name like 'iplog_%';
+---------------+---------+---------------+------------+
| table_name | engine | total_size_mb | table_rows |
+---------------+---------+---------------+------------+
| iplog_archive | ARCHIVE | 2.10 | 500000 |
| iplog_innodb | InnoDB | 30.56 | 500289 |
| iplog_myisam | MyISAM | 29.56 | 500000 |
+---------------+---------+---------------+------------+
3 rows in set (0.01 sec)
⑤測試select性能:
mysql> select * from iplog_archive where userid=250000;
+--------+--------+-----------+---------------------+
| id | userid | ip | visit_time |
+--------+--------+-----------+---------------------+
| 750001 | 250000 | 127.0.0.1 | 2010-02-01 10:54:20 |
+--------+--------+-----------+---------------------+
1 row in set (0.31 sec)
mysql> select * from iplog_innodb where userid=250000;
+--------+--------+-----------+---------------------+
| id | userid | ip | visit_time |
+--------+--------+-----------+---------------------+
| 750001 | 250000 | 127.0.0.1 | 2010-02-01 10:54:20 |
+--------+--------+-----------+---------------------+
1 row in set (0.48 sec)
mysql> select * from iplog_myisam where userid=250000;
+--------+--------+-----------+---------------------+
| id | userid | ip | visit_time |
+--------+--------+-----------+---------------------+
| 750001 | 250000 | 127.0.0.1 | 2010-02-01 10:54:20 |
+--------+--------+-----------+---------------------+
1 row in set (0.10 sec)
⑥測試insert性能():
使用python腳本再插入50w數據,查看插入性能,腳本如下,沒有寫的很復雜,測試InnoDB或者MyISAM要修改代碼
#!/usr/bin/mysql
import MySQLdb
conn = MySQLdb.connect(host="localhost",user="root",passwd="asdf",db="test",unix_socket="/data/mysql_3306/mysql.sock")
cursor = conn.cursor()
for i in range(500001,1000000):
sql = "insert into iplog_archive(userid,ip,visit_time) values(%s,'127.0.0.1',now())"%i
cursor.execute(sql)
cursor.close()
conn.commit()
conn.close()
archive
real 1m30.467s
user 0m22.270s
sys 0m12.670s
InnoDB
real 0m48.622s
user 0m18.722s
sys 0m9.322s
MyISAM
real 1m32.129s
user 0m13.183s
sys 0m5.624s
測試結果是archive可以大規模的減少空間減少%93(這個與表有關系),select性能介于MyISAM和InnoDB之間,大規模insert時效率比MyISAM和InnoDB高,至于原因“因為這個時候,CPU會取代I/O子系統成為性能瓶頸。別忘了Archive表比其他任何類型的表執行的物理I/O操作都要少。”
歡迎大家共同探討,包括測試用例以及任何想法。
新聞熱點
疑難解答