Chinaunix首页 | 论坛 | 博客
  • 博客访问: 50815
  • 博文数量: 12
  • 博客积分: 456
  • 博客等级: 下士
  • 技术积分: 125
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-12 14:38
文章分类

全部博文(12)

文章存档

2011年(1)

2010年(1)

2009年(10)

我的朋友

分类: Mysql/postgreSQL

2009-10-22 09:32:14

    两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用。
我作为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的,但是从我目前运维的数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,MyISAM绝对是我的首选。
原因如下:
1、首先由于互联网项目的特点,平台上承载的大部分项目是读多写少的项目,而MyISAM的读性能是比Innodb强不少的。
2、MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。
3、从平台角度来说,经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候MyISAM的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的binlog补上。如果是Innodb,恐怕不可能有这么快速度,因为Innodb定期用导出xxx.sql机制备份,而往往最小的一个数据库实例的数据量基本都是几十G大小。
4、从我接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的,很多人以为Innodb是行级锁,那个只是 where对它主键是有效,非主键的都会锁全表的。
5、还有就是经常有很多应用部门需要我给他们定期某些表的数据,MyISAM的话很方便,只要发给他们对应那表的frm.MYD,MYI的文件,让他们自己在对应版本的数据库启动就行,而Innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。
6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。
7、如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表。
当然Innodb也不是绝对不用,用事务的项目如模拟炒股项目,我就是用Innodb的,活跃用户几十万时候,也是很轻松应付了,因此我个人也是很喜欢Innodb的,只是如果从数据库平台应用出发,我还是会首选MyISAM。

另外,可能有人会说你MyISAM无法抗太多写操作,但是可以通过架构来弥补,之前我所管的数据库平台容量:主从数据总量在百T以上,每天20多亿的读写量。峰值达到每秒10万次。机器的平均负载在1-2,峰值不超过10左右。
 

对长期频繁操作的表,经常会出现show index from xxx出现非正常NULL

加参数就会自动去修复了
myisam_repair_threads = 1
myisam-recover=BACKUP

我自己做了一个实验,对一个记录时间戳的表进行myisam和innodb引擎变更的数据消耗比对
myisam引擎下数据消耗是
Avg_row_length: 28
Data_length: 12927712
Index_length: 12681216
innodb引擎下数据消耗是
Avg_row_length: 51
Data_length: 23642112
Index_length: 33161216
差不多innodb的比myisam引擎的磁盘消耗翻了(23642112+33161216)/(12927712
+12681216)约2倍。
如果在小项目情况下,这些数据量不算什么,但是对于百亿级的mic项目的话,恐怕就不能忽视的,
一般300G*6磁盘raid10之后大概是800G的数据量,如果用myisam可以支撑2个实例
(按每个实例300G来算)。
innodb的话,大概会要多支出2倍的服务器成本。

附实验例子:
mysql> flush table heart_beat;
Query OK, 0 rows affected (0.00 sec)

mysql> show create table heart_beat;
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| heart_beat | CREATE TABLE `heart_beat` (
`id` mediumint(9) NOT NULL auto_increment,
`status` varchar(10) NOT NULL default '',
`time` varchar(15) default NULL,
KEY `id` (`id`),
KEY `idx` (`time`),
KEY `idx2` (`status`,`time`)
) ENGINE=MyISAM AUTO_INCREMENT=461705 DEFAULT CHARSET=latin1 |
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show table status like 'heart_beat'\G
*************************** 1. row ***************************
Name: heart_beat
Engine: MyISAM
Version: 10
Row_format: Dynamic
Rows: 461704
Avg_row_length: 28
Data_length: 12927712
Max_data_length: 281474976710655
Index_length: 12681216
Data_free: 0
Auto_increment: 461705
Create_time: 2008-12-22 17:13:18
Update_time: 2008-12-22 17:13:19
Check_time: 2008-12-22 17:13:21
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)

mysql> alter table heart_beat engine=innodb;
Query OK, 461704 rows affected (7.90 sec)
Records: 461704 Duplicates: 0 Warnings: 0

mysql> show table status like 'heart_beat'\G
*************************** 1. row ***************************
Name: heart_beat
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 462060
Avg_row_length: 51
Data_length: 23642112
Max_data_length: 0
Index_length: 33161216
Data_free: 0
Auto_increment: 461705
Create_time: 2008-12-22 17:14:07
Update_time: NULL
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment: InnoDB free: 6144 kB
1 row in set (0.00 sec)

4.1.1.5 Clustered and secondary indexes
聚集索引(clustered index)将主键和记录直接挂钩,而且记录是根据主键来排
序的。当你通过主键来查询数据的时候,聚集索引非常快。因为它只要一次查询就
可以得到结果,而标准的MyISAM的索引需要两次查询,先查到索引,然后通过索引
得到的位置再去查数据。

4.1.1.6 Unique indexes versus primary keys
主键其实就是一种不能包括数值NULL的唯一索引。主键对于MyISAM引擎不是必需
的,但对于InnoDB 和BDB引擎来讲是必需的,如果你不声明,他们会隐含添加一个主键

但是对于一个16G内存的Dell 2950的机器上跑一个300G实例,同时每个表都是活跃
表的情况下,innodb的聚集索引消耗内存是非常大的,索引消耗会大于100G,内存
肯定是无法装得下的,会产生非常巨大的磁盘IO,不断对物理磁盘索引和内存索引的换入
换出。当然myisam同样也有换入换出问题,但是至少能比innodb支撑的久一些,因为
innodb的表索引至少比myisam的表索引大了2倍。

6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。

有无具体的数据来支撑这个观点呢?
innodb基于索引的update操作比MyIsam优秀了不止一点,这个不会仅仅通过分库分表就能赶上的.互娱所有游戏产品,产生的操作大部分是update,而据我了解基本上99%都选择了innodb.这足以说明问题.

如果基于读操作远大于写操作的应用,比如网站,那么用myisam还是可以的.也是不错的.但如果是写操作大于读操作的,innodb绝对是最佳选择.

另外,附上一个同事的博客.里面有几个文章,专门做了对mysql引擎方面的测试,供参考查阅.

http://rdc.taobao.com/blog/dba/html/295_insert_benchmark_for_myisam_and_innodb.html

测试表结构:

CREATE TABLE `test` (

`ID` bigint(20) NOT NULL auto_increment,

`INT_A` int(11) default NULL,

`INT_B` int(11) default NULL,

`INT_C` int(11) default NULL,

`STRING_A` varchar(50) default NULL,

`STRING_B` varchar(250) default NULL,

`STRING_C` varchar(700) default NULL,

PRIMARY KEY (`ID`),

KEY `IDX_TEST_IA` (`INT_A`),

KEY `IDX_TEST_IB` (`INT_B`),

KEY `IDX_TEST_SA` (`STRING_A`,`INT_C`)

) ;


 

数据量:总共10个表,每个表插入400w数据

并发数:每个表并发20个线程去执行插入操作,总共200个线程

数据特点:除了主键采用自增外,索引相关字段全是随机生成的。字符串的长度和内容都是随机的,平均长度为预定义的一半



 

X轴是unix时间戳,Y轴是十秒钟的插入量。从以上测试结果可以看出,InnoDB的插入性能随着数据量的增多一直在下降,而且表现相当不稳定。MyISAM的表现还是比较好的,虽然瞬时插入的谷值一直在下降,但是整体表现很稳定。

总的来说,Ext3的cache算法性能还是非常不错的,不愧是linux上面备受推崇的文件系统。InnoDB虽然提供了高可用性,但是插入性能方面的表现并不如MyISAM稳定。

阅读(1644) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~