首页 新闻 会员 周边

SQL delete语句删除缓慢

0
悬赏园豆:5 [已解决问题] 解决于 2019-06-20 09:34

SQL 这样1条语句:
delete from [Mes].[dbo].[缓存表] where 是否上传=1 and 记录时间<='2019-06-02 00:00:00'

删除数量约500000条记录,10分钟无反应;
因为有条件的删除,有什么可以快速删除,在线数据维护,不能清空表的数据?

问题补充:

数据量是50W,在电脑没有重启之前,这个操作怎么都完不成;
没办法了重启电脑,这个操作可以完成,时间大概在6-7S左右,这个删除操作还是比较慢的。

浪迹枫叶的主页 浪迹枫叶 | 初学一级 | 园豆:192
提问于:2019-06-03 22:34
< >
分享
最佳答案
0

1:聚集索引:
给是否上传和记录时间加上聚集索引、
2:数据有效期
你说的这种情况很少见,一般来说数据会有一个有效期。
比如有效期一个月,那你6月1号就要删除掉5月1号的数据,一天的数据量也就几十万(我之前工作的银行一天内的交易量)
我们处理数据的方式就是在凌晨系统空闲的时候用数据库定时任务操作数据
像你这种情况可以每天系统空闲的时候删除一部分,比如一天删除之前一个月的
另外我觉得你们应该考虑一下数据有效期的问题,每天只删除掉那一天过期的数据
3:分表
像银行交易表之类每天数据量很大的表,可以每天一张表存储当天的交易数据

收获园豆:5
小光 | 小虾三级 |园豆:1766 | 2019-06-06 10:56

客户要求数据存储5年,随时可以查询

浪迹枫叶 | 园豆:192 (初学一级) | 2019-06-06 11:46

@浪迹枫叶: delete from [Mes].[dbo].[缓存表] where 是否上传=1 and 记录时间<='2019-06-02 00:00:00'
我没想错的话,这个语句是把2019-6-2之前已经备份的数据给删除掉是吧,客户要求数据存储5年并不是在你操作的这张表中,我说的方法是针对这张表,并不是备份表
所以我在上面的三条方法还是可以用的,是对这张表用的

小光 | 园豆:1766 (小虾三级) | 2019-06-06 12:07
其他回答(5)
0

把是否上传和记录时间都设置索引

jqw2009 | 园豆:2439 (老鸟四级) | 2019-06-04 08:55

时间加索引有意思吗?每一个条数据的时间基本上都不一样吧

支持(0) 反对(0) 程序员修炼之旅 | 园豆:776 (小虾三级) | 2019-06-04 09:22

@猴子哥: 不一样就不用加索引??????????????

支持(0) 反对(0) jqw2009 | 园豆:2439 (老鸟四级) | 2019-06-04 09:24

@jqw2009: 哦,原来如此啊
嗯,我们平时没有给表的创建时间字段添加过索引
哈哈,也许是我不懂吧,算我长见识了吧

支持(0) 反对(0) 程序员修炼之旅 | 园豆:776 (小虾三级) | 2019-06-04 09:30

@猴子哥: sql语句条件里有这个字段的话加下比较好,用不到就无所谓了

支持(0) 反对(0) jqw2009 | 园豆:2439 (老鸟四级) | 2019-06-04 09:53

建立索引的话,对写入速度有比较大的影响吗?
建立过多的缩引,对数据的硬盘存储空间是否会不不建立缩引增长的要快?

支持(0) 反对(0) 浪迹枫叶 | 园豆:192 (初学一级) | 2019-06-06 10:41
0

你找看看表结构,那一些字段用到了索引,尽量用上索引字段作为条件,避免全表扫描

程序员修炼之旅 | 园豆:776 (小虾三级) | 2019-06-04 09:21

对, 还有你可以加上一个主键Id的最大值或者最小值作为条件,估计有一定的效率提升

支持(0) 反对(0) 程序员修炼之旅 | 园豆:776 (小虾三级) | 2019-06-04 09:23
0

这个表一共有多少条数据,如果不需要删除的数据远远小于需要删除的数据,试试这样:新建一个表,把不需要删除的数据查出来放到新表,把旧表删除,把新表重命名为旧表。这么多数据,建议问主分表分区存储,比如按时间分区,按是否上传分表,具体还得看业务

会长 | 园豆:12401 (专家六级) | 2019-06-04 09:33

这个转移表的方式行不通,在线数据库,有上位机一直在对这个表进行数据的操作,中间对表的删除和重命名新表会导致上位机数据库操作异常.

支持(0) 反对(0) 浪迹枫叶 | 园豆:192 (初学一级) | 2019-06-06 10:36

@浪迹枫叶: 要不你就分批删除吧,每次少删一点,多来几次

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2019-06-06 11:46
0

新建一张表Mes_test,然后insert into Mes_test select xxx from 原来表 where 是否上传=0 and 记录时间>'2019-06-02 00:00:00',然后truncate 原来的,把新建的表改个名字

正义的伙伴1994 | 园豆:165 (初学一级) | 2019-06-04 11:41

在线数据库不允许这样操作,导致上位机异常.

支持(0) 反对(0) 浪迹枫叶 | 园豆:192 (初学一级) | 2019-06-06 10:38

@浪迹枫叶: 你想到办法了吗

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2019-06-06 11:46
0

500多万行,删除慢一点也是正常。有一种优化方法是,假如你有3年的数据,可以分三次删除,第一次删两年前的数据,第二次删一年前的数据,最后删今年的数据。

AYard | 园豆:436 (菜鸟二级) | 2019-06-04 19:09
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册