有这样一个表mytable
A bigint(20) primary key. 
B varchar(2000), 
C varchar(500), 
D tinyint(2).表中有300万条记录。现在要select * from mytable where A=? 这样的语句处理时间小于1毫秒,insert,update操作也是很简单的insert mytable (A,B,C,D) values(?,?,?,?); update也是单表根据key更新。
我测试大部分时间都超过1毫秒了,偶然小于1毫秒,大家有什么优化方案没有,数据库是MYSQL.
我想了,更新和插入可以采取异步更新到数据库的方式,但是查询呢??说明:如果同时把这些数据存在应用系统的内存,是可以解决的,但是耗费内存太大,而且不能持久保存,所以单纯这个方案否定了。大家帮忙看看,谢谢了。

解决方案 »

  1.   

    打开日志没有?有无TRIGGER、表间关系?
    一般来讲,SELECT速度>insert,update、DELETE,
    如果是大量插入数据,用SOURCE OR LOAD DATA
      

  2.   

    没有表关系,“SOURCE OR LOAD DATA”用不上。
      

  3.   

    你的表的存储引擎是什么?
    有多少索引?show create table xx
    show index from xx看一下.
      

  4.   

    就一个mobile主键索引,
    存储引擎Myisam.
      

  5.   

    插入300万达到以后,以后长时间都是select和update比较多。insert基本比较少,除非没有达到300万的哪些数据。300万数据每条都是唯一的
      

  6.   

    IMHO: 1ms这个要求可能比较难建议适当增大key_buffer_size参数试试,然后还要开cache
      

  7.   

    是呀,就是因为有难度,我才来求帮助,我也做过不少数据查询相关的性能优化,但是这个1毫秒以下的指标,把我难住了。
    另外,楼上说的cache是查询缓存吗,我考虑过这个,但是mysql 的query cache在update操作后,缓存中会清除对应的KEY的缓存,我的业务需求是:select update的频率差不多,一个事务一般先select ,然后update,这样看来,好像查询缓存用不上。
      

  8.   

    为什么纠缠于1ms你要知道机器一个寻道周期可能都不只1ms,你这个完全不可控
      

  9.   

    select update的频率如果差不多的话,可能需要反过来,关闭cache或者使用
    SELECT SQL_NO_CACHE * FROM ...
      

  10.   

    CPU每个时钟信号周期的单位一般都用纳秒表示的。1纳秒=1000000毫秒
      

  11.   

    读文件,写文件的效率比数据库高多少? 我记得以前测试好像跟DB差不多,准备尝试下,因为DB其实也是写文件嘛。
      

  12.   

    关于时间的最小单位,可以参考:
    http://blog.csdn.net/chuan122345/archive/2009/12/11/4985463.aspx1秒 =1000000000000000飞秒 =1000000000000皮秒  = 1000000000纳秒 = 1000000微秒 = 1000毫秒
    1秒 = 1000000000000皮秒  = 1000000000纳秒 = 1000000微秒 = 1000毫秒
    1秒 = 1000000000纳秒 = 1000000微秒 = 1000毫秒
    1秒 = 1000000微秒 = 1000毫秒
    1秒 =  1000毫秒
      

  13.   

    你没听懂,人家是让你启动的时候读一遍、关闭的时候写一遍,跟每次都有Disk I/O操作有本质不同
      

  14.   


    比数据库高很多。 一个是直接通过操作系统操作磁盘IO,一个是提交个数据库系统,然后由数据库系统来操作操作系统写磁盘IO
    这一点无需置疑。当然也和你的代码效率有关。
      

  15.   

    对mysql的性能我专门做过测试,请查看:
    http://blog.csdn.net/forever_feng/archive/2009/10/16/4679233.aspx
      

  16.   


    那个没什么意义,1秒CPU周期再多,架不住做到事情多。
    光遍历一遍“select * from mytable where A=100”这三十几个字符,可能就需要大概100个周期,这还不是解析SQL语句。
    感觉,还是尽量使用CPU+内存,避免disk i/o。如果用索引的话,最好利用hash类型的索引,而不是btree(但不知道PK可不可以hash,貌似好像不可以)
      

  17.   

    呵呵,我只知道MEMORY存储引擎用的是hash索引,所以速度快,我用navicat存储引擎建立索引,好像只有普通索引,唯一索引和全文索引,这几个索引类型选择。
      

  18.   

    navicat engine没用过,但是据你说的,你选的是index kind不是index type(参照MySQL Administrator的命名)PK貌似可以hash,不过我用的是innodb
    CREATE TABLE  `test`.`a` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `text` varchar(45) NOT NULL,
      PRIMARY KEY (`id`) USING HASH,
      KEY `Index_2` (`text`) USING HASH
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      

  19.   

    呵呵,没有navicat engine,我打错了,navicat是MYSQL可视化工具,你说的方法,我尝试下,多谢了。
      

  20.   

    但是一旦PK用Hash了,后果也是很明显的,没问题吗?
      

  21.   

    hash索引只能由于单个的=比较,其他的>,<,还有in(in这个我有点不确定)什么的都用不上这个索引了。
      

  22.   

    搞个大内存的机器,在内存里做一个hash table,把数据都加载到内存里,定时刷新到硬盘上
    这样读写操作都在内存里进行,效率应该要好一些
      

  23.   

    只把 id 保存在内存里可以吗?300w 数据大概也就需要百十来M的内存而已。如果可以的话,就自己实现一套管理查询算法,然后实际的数据体以文件的形式保存在磁盘上。当然要考虑查找/更新算法效率优化、读写冲突、IO缓存等等,基本上相当于把数据库的存储引擎和索引算法重新实现了一遍(简化版),hehe理论上讲,这样肯定能做到比数据库的效率高。但要“确保1ms以内”说到底是不可靠的,毕竟你的操作系统就不是“实时操作系统”。
      

  24.   

    搞几百个表,用key计算表的名字,这样每个表里面只有几万条记录(如果key是比较平均的话),时间就好控制了。因为你所有的操作都是根据key来的,所以可以直接针对某个表操作,而且key是数值,做一个hash也很快(或者干脆取最后几位)。如果将来要对所有的数据同时操作,可以考虑merge engine
      

  25.   

    楼主的需求最好是用文件处理了,这样可以根据自己的实际情况进行C语言甚至汇编代码级别的优化。
    如果用MySql,楼主可以尝试一下:
    假设楼主的并发量不大的情况下
    1,采用MyISAM引擎.
    2,以硬盘空间换取时间,楼主的varchar字段能否给成固定长度的char字段。这样每行的长度固定,mysql处理时间上更快。
    3,关闭QueryCache,因为你的表老修改,开QueryCache降低性能。
    4,查看MYI文件大小,在内存中KEY_Buffer_Size大小一定要比MYI文件大。确保所有关于字段A的索引都能装入内存(估计300万记录,至少需要60M吧,楼主的硬件语序的话,设置256M能成?)
    5,增加一个启动时运行的Sql脚本,在启动的时候就将索引load到内存。
    6,考虑插入锁优先级比Select锁低。
    7,Primary Key的优化,根据楼主A字段的值,查看是否有更好的优化方式,是采用Btree还是hash等。
      

  26.   

    另外楼主的业务为何需要先查询在插入呢。可否考虑直接插入如果存在就update呢,这样Mysql一个语句搞定:
    insert .... ON DUPLICATE KEY UPDATE ....
      

  27.   

    你讲得很有道理,看得出来你对MYSQL很精通哈。