2

我在某个日期时间段(即 05/01/2012 到 05/31/2012)的数据库上运行复杂查询列表。然后我需要对 06/01/2012 到 06/30/2012 运行相同的查询。然后加入结果以用于报告目的。

在查询中,我使用了几个表变量来保存临时数据。因为数据库很大,所以表变量也很大。有没有办法可以重用这些表变量?

DROP,截断将不起作用。我必须从@table 中删除所有数据吗?如果是这样,它会很慢吗?因为它有很多数据,我是否必须对 @table 进行批量删除?

顺便说一句,由于系统的设计方式,我必须将所有查询放在一个 SP 文件中,不能调用函数或其他 SP。

谢谢

==============================

查询中没有循环。它的工作原理如下:

选择.....选择......更新......加入......

对日期 05/01/2012 到 05/31/2012 进行一组查询。然后需要对 06/01/2012 到 06/30/2012 进行同一组查询。

在查询中,里面有很多逻辑,所以我们不能将这两个组合成一组查询。由于系统设计的原因,我们不能调用函数或SP进行查询。必须执行第一组查询,然后依次执行第二组查询。

问题是数据太多,@table 太大。如果我们可以重用@table,它将解决问题。

谢谢

================================

是的,现在,相同的代码,对于 2 个不同的日期时间间隔重复两次。但是,在代码中,它有一些逻辑内部,基于日期时间的差异不同的过程。抱歉,我无法发布实际代码。但是,这个过程就像一个SP,以不同的日期时间段作为参数。

但是,在这种情况下我不能使用 SP/function,所以必须对相同的代码进行两次硬编码。理想情况下,每次我重复代码时都需要使用不同的@table(现在,我需要重复3次),但是由于数据大小,如果我重复3次@table太大(每次需要多个@table做逻辑部分)。

也许我最好使用临时表?所以我可以在开始新的“重复”时放弃它?

谢谢

4

2 回答 2

15

表变量没有记录在当前数据库中,也不受事务的影响。为什么你认为截断或删除会比删除更快?你试过这个吗?

DECLARE @f TABLE(id INT);

INSERT @f SELECT 1;

BEGIN TRANSACTION;
DELETE @f WHERE id = 1;
ROLLBACK TRANSACTION;

SELECT id FROM @f;

没有结果。现在,如果删除已完全记录在当前数据库中(这DELETETRUNCATE普通用户表慢),您会期望DELETE已回滚,并且SELECT应该已返回数据。但是不,删除不是事务的一部分。那么,您可以从逻辑上得出结论,如果允许后者,即使不相同DELETETRUNCATE也会非常相似。

如果必须使用表变量,只需使用删除即可。如果您发现它很慢,可能不是因为删除,可能是因为您在循环中重复使用表变量,而不是使用基于集合的操作。但是,当然,您比我们任何人都处于更好的位置来测试如果您使用两个不同的 @table 变量与重新使用单个表变量并在两者之间发出删除,您的代码会慢多少。但我仍然认为你的整个过程需要重新调查,因为它在很多层面上对我来说都不是最理想的。

于 2012-07-23T21:45:50.260 回答
1

当然可以,但是您真正想要的不是表参数,而是需要一个临时表。

CREATE TABLE #my_temp_table (column1 int, column2 varchar(max), ...)
INSERT INTO #my_temp_table (column1, column2) VALUES (...)
-- Use the temporary table here
DELETE FROM #my_temp_table
INSERT INTO #my_temp_table (column1, column2) VALUES (...)
-- Use the temporary table again
DROP TABLE #my_temp_table

编辑:提交者可能会说“我不能使用表变量,因为它被传递给我的带有 READONLY 标志的存储过程”。在这种情况下,他可能会从将其转换为临时表中获得一些好处。

附带说明一下,尽管 SQL Server 的文档声称情况并非如此,但我已经看到临时表比表变量执行得更好的实例。我相信这是因为我把我的 TEMPDB 放在了一个单独的磁盘上,它有很多可用的 IO 容量。

但是请记住,临时表存在命名问题——如果存储过程试图为临时表创建命名冲突,您可以锁定它。表变量不会遇到这个问题。

于 2012-07-23T21:46:50.430 回答