【发布时间】:2009-04-03 16:03:16
【问题描述】:
我们的服务器应用程序全天以每秒 1000-2000 行的速度接收有关要添加到数据库的行的信息。表中有两个互斥列唯一标识一行:一个是数字标识符,称为“tag”,另一个是 50 个字符的字符串,称为“longTag”。一行可以有一个标签或一个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) 标签非零且 longTag 为空:这是一个带有数字标识符的日间交易。 2) tag 为零,longTag 有一个非空字符值。这是带有字母数字标识符的日间交易。 3) tag 为零,longTag 为空:这是一个开仓。 4) tag 非零且longTag 有一个非空字符值。我们的服务器软件阻止了这种情况的发生,但如果发生这种情况,longTag 将被忽略,并且将被视为与案例 #1 相同。同样,这不会发生。
【问题讨论】:
-
只是出于好奇,你在做什么以如此快的速度生成数据?
-
您能否详细说明您的 tag 或 longTag 是否可以变为 NULL?此信息对于索引问题可能很有趣。而且 - 如果它们是互斥的,它们不能被折叠成一列吗?
-
这是一个交易服务器。每条记录都是股票或期权交易。
-
我会详细说明——我要去开会。 :) 大约 30 分钟后回来。
-
@Tomalak:我添加了另一个关于 NULL 标签或 longTags 的编辑。它们也不能被折叠,因为其他系统是围绕它构建的——一些我们无法控制的系统。基本上,我致力于在我之前做出的许多非常糟糕的决定。我希望我能改变很多事情。
标签: sql-server performance tsql