【发布时间】:2015-05-22 16:30:33
【问题描述】:
假设我有一个有 5 列的表:
Id int primary key
Date datetime
Value double
Fund_id reference
FundModel_id reference
FundDataField_id reference
此表有 37 000 000 行。
每个基金大约有 4000 行。从该表中删除行的最佳且快速的方法是什么? 我需要一次删除大约 7000000 行,但这大约需要 10 分钟,对我来说这已经很多了。
目前我按 Fund_Id 删除行,如下所示:
Delete from FundYearDetail where Fund_id In (2054,2056,2058,2059,2061,2063,2064,2065,2066,2067,2069,2072,2073,2076,2078,2079,2080,2081,2082,
2086,2088,2090,2093,2095,2096,2097,2099,2101,2102,2103,2104,2105,2106,2107,2109,2110,2114,2115,2116,2117,2118,2119,2342,2125,2126,2127,2128,2129,2130,2131)
这条语句将影响大约 200 000 行并且需要很长时间才能完成,将这条语句分成 2 个查询我得到了更好的性能,每个查询大约 4 秒。
有人知道更好的解决方案吗?
注意:如果有人知道使用 Nhibernate 的更好解决方案,我正在使用 Fluent NHibernate 进行数据访问,请告诉我。 如果我要做一个存储过程,这会提高我的性能吗? 谢谢。
【问题讨论】:
-
这是一次性操作,还是您需要添加到应用程序中以使您的软件的最终用户可重复并完成的一项功能? (无论如何,我可能不会使用 NH,假设您正在为所有这些实体补水只是为了删除它们)
-
好吧,我在正常情况下使用 NH 访问数据,我想删除所有这些行只是因为我正在从 csv 文件执行大数据导入,我正在使用 sqlbulkcopy 执行此操作,所以在导入数据之前我想要删除所有将受到影响的行而不是更新它们,因为我认为更新这么多行将花费更多时间而不是使用 sqlbulkcopy 插入它们。
-
是的,我正在寻找一种可重复的解决方案,但如果您也有一次性解决方案,请告诉我您有哪一个,我认为您不会建议重新创建表格...
-
与大更新一样,我会尝试使用 while 循环,一次删除 50,000 条或更少的记录。
-
@TabAlleman 所说的是在 sql 中进行大型删除的最佳方法 - 这里已经回答了一些不同的问题,它们使用循环、goto、top 子句来完成这项工作。我在使用 NH 进行任何批量操作时一次又一次地遇到问题——最好的办法是将整个操作推送到数据库中——存储过程集、SSIS 等——然后你可以更有效地进行更新,也许避免删除。尤其是如果你有外键,删除的效果会非常好。
标签: c# sql sql-server stored-procedures nhibernate