小弟手有一个项目,数据量非常大,预计为26亿条/天,30%集中在最忙的两个小时,算下来每秒需要INSERT或UPDATE两万个请求.
我的设计是每来一个记录就UPDATE一个2万千记录的表,如果记录不存在,则INSERT.
现在我在一台IBM P680(8CPU 16G内存 ESS800盘阵) 机器上装了一个MYSQL,使用INNODB引擎,开了1G的buffer.经过测试,单进程最大INSERT速度为3500条/秒.
内时开三个进程向同一张表里INSERT时,速度为10000条/秒.这时CPU已经达到了60%的负荷.但是这种情况只是一个测试,业务处理逻辑还没有加上去.我这里想请较一下做OLTP系统的专家,有谁做这种类型的应用.小弟平时用的是DB2,做OLAP的应用,对单事务处理方面不是很熟,请大家指教一下.

解决方案 »

  1.   

    MYSQL完全可以.
    表结构:

    mysql> show create table song\G
    *************************** 1. row ***************************
           Table: song
    Create Table: CREATE TABLE `song` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(45) NOT NULL,
      `datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `rank` varchar(45) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=20001 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)

    存储过程:
    DELIMITER $$
    DROP PROCEDURE IF EXISTS `sp_insert`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_insert`(IN number int(11))
    BEGIN  declare i int(11);  set i = 1;  WHILE i <= number DO    if mod(i,2000)=1 then       set @sqltext =concat('(''',concat('woshiduide',i),''',''',now(),''',',ceil(10*rand()),')');    elseif mod(i,2000)=0 then       set @sqltext=concat(@sqltext,',(''',concat('woshiduide',i),''',''',now(),''',',ceil(10*rand()),')');       set @sqltext=concat('insert into song (name,datetime,rank) values',@sqltext);       prepare stmt from @sqltext;       execute stmt;       DEALLOCATE PREPARE stmt;       set @sqltext='';    else        set @sqltext=concat(@sqltext,',(''',concat('woshiduide',i),''',''',now(),''',',ceil(10*rand()),')');    end if;    set i = i + 1;  END WHILE;  if @sqltext<>'' then     set @sqltext=concat('insert into song (name,datetime,rank) values',@sqltext);     prepare stmt from @sqltext;     execute stmt;     DEALLOCATE PREPARE stmt;     set @sqltext='';  end if;END$$
    DELIMITER ;
    调用存储过程:mysql> call sp_insert(20000);
    Query OK, 0 rows affected (1.04 sec)
    结果
    mysql> select count(1) from song;
    +----------+
    | count(1) |
    +----------+
    |    20000 |
    +----------+
    1 row in set (0.03 sec)
      

  2.   

    但这是在数据库内部作INSERT呀,有没有外部接口的测试呢?
      

  3.   

    这个啊,还是去请教mysql官方支持吧
      

  4.   

    有没有减少IO的方法呢?
    我的QQ:2745071 大家指点一下吧。
      

  5.   

    我的建议:1. Insert delay
    在MyISAM表中可以使用该方法。当然,前提是你的需求MyISAM引擎可以满足。
    用Insert Delay插入的效率很高,你可以试试。2. Bulk Insert
    Mysql支持一次执行多条Insert语句。这种方法较常用。
    前端使用队列技术,定期/定量插入数据(比如没1000条数据插入一次,或每一秒插入一批)。
    这种方法能有效降低IO压力,当然,需要在前端做相应的技术改造。BTW,我个人的观点是象如此大规模的数据收集工作,最适合的应该是log,用文本来做数据log。
    对你的需求不了解,只是我个人的经验。