锁定老帖子 主题:关于删除数据库中百万级数据的解决方案
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-12-27
在这之前也对not in 和not exists进行过测试,但是最后的结果是查询使用的时间是基本是相同的(InnoDB引擎) 所以在上述说明中并没有说not exsts ,在对myisam引擎中相对的速度会快(因为不在同一个服务器上的两个相同的数据,数据库引擎不一样)。这种只是对mysql的两种引擎的比较,下面说1楼中所说的问题,在每个表中都建立有索引,虽然查看数据相对的比较快,但是在删除中查询虽然相对较快但是牵扯到数据更新的话那速度应该是相对慢的,根据删除的结果,大约需要10个小时左右(具体时间没有试),像这种的话我一晚上的更新时间也是不够的(所以弃而不用)。3楼所说的删除数据一条一条的删除这个问题当时也想过,只是不想在用in的子查询,所以才用一条一条的删除,但是为什么不一次删除也是有原因的,针对当时的问题也曾经执行过,执行所用的时间也是巨大的,也是没有办法的事(具体的时间上线时间也是定在3个小时)。回答5楼的问题,不是我想用,是实际情况决定的,所以在这里 一下。怎么说呢理论永远都是理论等用到实际就会明白什么是对的,什么的错的
|
|
返回顶楼 | |
发表时间:2010-12-27
1.不要迷信所有的查询必须使用索引。
2.查询需要删除的数据的sql,不会变成这个case的性能瓶颈。 3.如果选择用存储过程的话,就要减少 pl/sql引擎 和 sql引擎的切换。 |
|
返回顶楼 | |
发表时间:2010-12-27
zy8643954 写道 1.不要迷信所有的查询必须使用索引。
2.查询需要删除的数据的sql,不会变成这个case的性能瓶颈。 3.如果选择用存储过程的话,就要减少 pl/sql引擎 和 sql引擎的切换。 一看就是高手,能不能给小弟详细说个例子呢? |
|
返回顶楼 | |
发表时间:2010-12-27
还有也许 写道 zy8643954 写道 1.不要迷信所有的查询必须使用索引。
2.查询需要删除的数据的sql,不会变成这个case的性能瓶颈。 3.如果选择用存储过程的话,就要减少 pl/sql引擎 和 sql引擎的切换。 一看就是高手,能不能给小弟详细说个例子呢? 我才入门呢,我在前面 写了一个存储过程的。楼主没看见? |
|
返回顶楼 | |
发表时间:2010-12-27
不知道楼主用的是什么数据库,
至少在db2和mysql下delete基本属于噩梦. truncate ,load replace之类的命令还是比较适合你的 . 当然,如果有分区表的话可以考虑drop Partation一类的指令. |
|
返回顶楼 | |
发表时间:2010-12-28
可以考虑切表呗
|
|
返回顶楼 | |
发表时间:2011-01-19
还有也许 写道 兄弟们呀,我现在还有个头大的问题,就是我们的customer已经860万了,而中间表m_customer_category 也有900多万了,如果按类型查找客户资料的话巨慢,如何解决呀,就是customer,m_customer_category,custoemr_category三张表多对多关系,怎么按类型快速查找呀
我真的不明白你们为什么一定要使用多对多的关系,现在你的数据量已经达到这种级别了,你可以考虑第一、使用分区分表;第二、引入Lucene,将客户资料的搜索交给全文索引来处理,他可以解决你搜索的性能。如果对实时性要求很高的话,你可以使用Lucene3.0,Lucene2.0不支持实时索引。 |
|
返回顶楼 | |
发表时间:2011-01-19
一般删除慢都是应该io忙或内存不够。io不行有可能是sql不好,也有可能本来io能力就不行,或者你的数据文件分配有问题。io还可能是因为log日志引起的。
所以在删除的时候是否可以考虑让被删除的表不支持事务,不记log。 否则只能想办法小批量删除提交,不要在一个大事务里面做。 其实你也可以考虑用jdbc把要删除的id查出来,然后批量删除。也许这样会更快,我这边就有类似的功能,也是几百万数据量,直接用sql还没有用jdbc查出来删除快。 |
|
返回顶楼 | |
发表时间:2011-01-20
xiaoshan5634 写道 还有也许 写道 兄弟们呀,我现在还有个头大的问题,就是我们的customer已经860万了,而中间表m_customer_category 也有900多万了,如果按类型查找客户资料的话巨慢,如何解决呀,就是customer,m_customer_category,custoemr_category三张表多对多关系,怎么按类型快速查找呀
我真的不明白你们为什么一定要使用多对多的关系,现在你的数据量已经达到这种级别了,你可以考虑第一、使用分区分表;第二、引入Lucene,将客户资料的搜索交给全文索引来处理,他可以解决你搜索的性能。如果对实时性要求很高的话,你可以使用Lucene3.0,Lucene2.0不支持实时索引。 分区分表已经晚了吧,这是在规划项目时考虑好的,第二种很实用,我去学习一下Lucene的使用。 |
|
返回顶楼 | |
发表时间:2011-02-20
不知道你们做这个维护工作的时候,数据库是否可以停机,或者说只能读不能写,时间有多长。(估计是可以的,你之前让它这么满负荷跑了N小时,这段时间估计其他什么程序都干不了活)。
我也谈谈我们的经验,不是删除无效数据,而是创建新表,获取有效数据: 1. 或者凌晨找个时间禁止写入, flush tables with read lock; 2. 然后创建一个m_customer_category_new新表, 分好区partition by xxx 3. 用java多线程程序,把m_customer_category中有效数据用多线程程序插入进去,每个区1个线程,速度会很快。(在我们的项目innodb上,每秒插入1万条左右) 4. 数据准备好以后,再创建索引(无索引的表,插入操作比有索引的快很多) 5. 将原来的表干掉,新表rename 6. 最后再把lock取消, unlock tables; 这样分区优化也做了,数据也删除了。 |
|
返回顶楼 | |