问题: 目前有一张表 Table 数据量是 100W 左右,现在有列 A到Z,每天都有几千次的更新,更新频繁,查询的条件又是根据这A到Z 来判断的,因为查询速度太慢,想在这些列上建立索引,建立好后,查询速度提升了很多,但是影响了增删改操作,因为列数比较多,更新的次数太频繁,建立索引后,系统操作时可能会经常死,但是不建立索引,查询的又太慢。
对于这种情况,一般有几种解决方法,详细点,豆全部奉上。
有没有看看什么是瓶颈?磁盘IO ?CPU耗时? 最好在profile里面查看一下。
不知道你数据库的硬件配置,从这个数据量来看,数据文件和索引文件都很大,可能IO是瓶颈,考虑一下这部分数据是否可以放SSD硬盘,再增加内存,能缓解IO瓶颈。 这个是从硬件角度处理
还有,可以考虑调整某些字段。我的经验,字符型字段比较耗性能。如果有些字段存的是字符,但是这些字符又是标准的选项,那可以考虑将这字段换为int型,指向标准选项的索引。这个是从软件角度处理
再,你表的主键是啥类型?
说的很好
用缓存
把表结构也写出来
能详细点吗,比如用缓存,怎么使用
另外加一个表,加索引,只做查询。如果数据可能缓存,再加上缓存就更好了。
说的很好跟我想的一样,因为涉及到钱的问题,数据必须是实时的,实时同步又是新问题了。
@高升2012: 可以同时插入2个表,就是实时的。
@清海扬波: 额 同时插入2个表还叫做只做查询吗。
@tomcat1988: 如果只能优化查询,不考虑其他的解决方案的话,这个问题没有答案,只能叫他加硬件神马的了。
@清海扬波: 同时插入两张表,增删改的性能会受影响,现在查询优化已经没大的问题了,主要就是增删改的影响。
@高升2012: 索引本身就是提高查询速度,影响插入修改的性能,所以要平衡好
读写分离,再就是做缓存
说的很好跟我想的一样,读写分离是一个不错的方案,因为涉及到钱的问题,数据必须是实时的,实时同步又是新问题了。
可不可以这样 根据你数据 缓存一部分以前的数据 比如1年前的全部缓存 其他的再从数据库取
如果是报表的话把表按月,按季度设计。
用存储过程创建表。
实时同步可以用SQLDependcy啊
个人认为最开始的数据架构就没做好。
一个表放100W条数据,操作,查询都访问这个表肯定影响效率。最好是做分割。10W量级的为一个表(或者单独的数据库。)。那么100W数据就变成10个表来存储了。另外单独建立一个库 这个库只保存用户最索引ID 如 userid tableid .通过这个目录库来决定用户要访问和操作的的表。就是分布式管理,我语言表达差,就是这个意思。什么缓存都是浮云,缓存需要消耗大量的硬件资源的。
考虑到分表,由于100W的数据量不是很大,所以暂时没必要动这块,现在是希望做最少的修改,提高最大的性能。
这种分表方式对有些需要查询多个历史期间记录的查询就不适用了。
硬件允许的话 用两个数据库 做读写分离 可以有效的缓解问题。
或者不一定非得在数据库中解决所有问题吧 可以试试在程序中增加缓存层, 查询尽量在缓存中进行, 写入则让相应的缓存失效。
读写分离是好,可是担心数据同步问题,这部分数据同步测试也不方便
目前只考虑数据库操作,程序的操作暂时不想动。
@高升2012:
水平分割, 建立几个相同的表, 这样索引变小, 插入会变快。
如果不想大改动数据库 可以考虑尽量批量操作, 在插入更新 之前 先把不必要的索引删除, 更新操作之后 再加回来。
@gunsmoke: 我想反对你一万次。
@Home.Lu:
写写理由吧。
建议主要考虑80%常用到的查询,剩余较少的查询条件使用到的字段,先不要建立索引,试一下吧。
在制造企业中100W+的数据表是很常见的。但索引要建到20多个的就少见了,
如果真得需要,建议使用覆盖索引。
可以试下将建立的索引存储改到其他文件组,使用单独的磁盘分与数据文件分开。
可以试下将建立的索引存储改到其他文件组,使用单独的磁盘分与数据文件分开
很简单,拆表么,既然查询都要用到那个a到z的列,那就按照这个列的值来拆表。另外说一下,每天更新上千次真心不算多啊
如果这样横着拆会影响某些查询,也可以考虑竖着拆。如果有一些大字段的话,最好把大字段单独拆出一张表来,一般大字段只有查单条纪录的时候才会用到,拆出大字段后,源表的查询消耗io会减少很多
确实不多,但是更新的字段多,行多所以会慢,有利有弊吧。