2009-11-18 104 views
4

我有一个SQL Server 2008数据库,大约有1400万行。在这里面有两个表为什么TOP或SET ROWCOUNT使我的查询如此缓慢?

Table1 
    rowId int, primary key 
    someData1 int 
    someData2 int... 

Table2 
    id int, primary key 
    rowId ==> int, refers to the rowId from Table1 
    someCalculatedData int... 

    Table2.rowId is not a foreign key, but I did make a Non-clustered, Non-Unique index on it 

当我输入我插入所有数据到表1,然后发现没有在表2中的条目以及将数据插入此表行的数据。

我一次选择250,000行,处理数据并将它们插入到表2中,然后查找下一个250,000行等等,直到它们没有任何表中没有任何行的行进入表2。

select TOP 250000 rowId from Table1 
     where NOT EXISTS (select rowId from Table2 where Table1.rowId=Table2.rowId) 

该查询速度真的很慢,现在需要两分钟才能获得下一批。 如果我在没有使用TOP或SET ROWCOUNT关键字的情况下运行查询并获取所有行,则查询以大约15秒的时间返回结果。

有谁知道为什么TOP和SET ROWCOUNT导致查询拿这么多再然后让所有的数据?

我可以提高查询的性能和每一次仍然只能获得数据的一个子集?

+1

查询是否在〜15秒内退回所有行,或者它*开始*返回行,15秒后第一行? – 2009-11-18 23:11:34

+0

@Remus我的想法确切。 – 2009-11-18 23:14:29

+0

如果我在Sql Server Management Studio中运行查询,我可以在5-8秒后看到一些结果,并且在没有TOP关键字的情况下所有结果都是15秒。如果我包含TOP关键字,我不会在2分钟内看到任何东西。 – nick 2009-11-18 23:15:21

回答

1

显然我的索引或Table2.rowId索引统计信息不新鲜的TOP/SET ROWCOUNT查询的查询计划表现不佳。

我重组/重建索引,为TOP/SET ROWCOUNT查询的查询性能得到极大改善。

+1

如果任何人都可以阐述发生了什么和/或如何诊断/更快识别这些问题的细微差别,请分享:) – nick 2009-11-19 00:10:17

1

这是因为所有查询都需要在服务器上运行,然后服务器才能决定哪些“顶以” 250,000行的。只有这样数据才能通过网络回到客户端。

如果没有“top”语句,服务器将立即开始发送数据,尽管我怀疑从服务器发送并由您的机器接收的所有数据的总时间可能类似于包括顶部。

+0

有趣....所以,有没有一个聪明的解决方法? – andy 2009-11-18 23:17:59

+0

不幸的不是。无论是在1400万行服务器上工作,还是在客户端机器上工作,仍然需要完成。 – 2009-11-18 23:25:04

+0

如果我选择Table1中的所有rowID而不是Table2中的查询,本地和远程查询似乎都可以接受。如果我尝试获取它们的任何子集,则需要更长的时间。 – nick 2009-11-18 23:29:57

3

看看这有助于

select top 250000 t1.rowid 
from Table1 t1 
left outer join table2 t2 
on t1.rowid=t2.rowid 
where t2.rowid is null 
+0

这是一个很好的建议。特别是在子查询中“不存在”可能会很慢。 “left join where null”会给你同样的东西。 – DanO 2009-11-18 23:35:03

+0

正是我想推荐的!取决于你设置的这个开关的索引可能会有很大的不同。 – KSimons 2009-11-18 23:42:56

相关问题