我们的服务器应用程序每天以1000-2000行的速率接收有关要添加到数据库的行的信息.表中有两个互斥的列,用于唯一标识一行:一个是名为"tag"的数字标识符,另一个是名为"longTag"的50字符串.一行可以有标签或longTag; 不是都.
从套接字进入的每一行可能已经存在,也可能不存在于表中.如果存在,则必须使用新信息更新该行.如果它不存在,则必须添加.我们使用SQL 2005,在少数情况下甚至使用SQL 2000,因此我们无法使用新的MERGE关键字.
我现在这样做的方法是构建一个巨大的DELETE语句,如下所示:
DELETE from MyRecords WHERE tag = 1 OR tag = 2 OR longTag = 'LongTag1' OR tag = 555
...每个传入的行都有自己的'OR tag = n'或'OR longTag ='x''子句.
然后,我使用ISQLXMLBulkLoad执行XML批量加载,一次加载所有新记录.
巨大的DELETE语句有时会超时,需要30秒或更长时间.我不知道为什么.
当记录从套接字进入时,它们必须插入或者必须替换现有的行.我这样做是最好的方式吗?
编辑:新行与替换行的比率将非常倾向于新行.在我看到的生产数据中,每次修正通常会有100-1000个新行.
编辑2:插入和删除都必须作为单个事务处理.如果插入或删除失败,则必须同时回滚它们,使表处于插入和删除开始之前的状态.
编辑3:关于NULL标签.我需要先简要介绍一下系统.这是一个交易系统的数据库.MyTable是一个包含两种交易的交易表:所谓的"日间交易"和所谓的"开仓".日间交易只是交易 - 如果您是期权交易者并且您进行了交易,那么该交易将是该系统中的日间交易.开盘头基本上是您的投资组合的摘要,直到今天.开仓和日内交易都存储在同一个表中.日间交易有标签(longTags或数字标签),而开仓位则没有.开仓时可能有重复的行 - 这很好且正常.但是,日交易不能有重复的行.如果日间交易与数据库中已存在的某个记录具有相同的标记,则表中的数据将替换为新数据.
因此tag和longTag中的值有4种可能性:
1)tag为非零且longTag为空:这是一个带有数字标识符的日间交易.2)tag为零,longTag具有非空字符值.这是一个带有字母数字标识符的日间交易.3)tag为零,longTag为空:这是一个开放位置.4)标签非零,longTag具有非空字符值.这可以防止我们的服务器软件发生的每一件事,但如果它发生了,那么longTag将被忽略,它将被视为与案例#1相同.同样,这不会发生.
我认为将巨大的DELETE语句拆分为2 DELETE可能会有所帮助.
1 DELETE处理标记和单独的DELETE来处理longTag.这将有助于SQL服务器选择有效地使用索引.
当然,您仍然可以在1 DB往返中触发2个DELETE语句.
希望这可以帮助