2013-07-12 109 views
1

我使用SQL Server 2008 R2,我有表:一个简单的选择SQL语句

Book: id, name, ... >> 3500 rows 
BookChapter: id, bookid, content(nvarchar(max)... >> it has about 300000 rows 

的2

现在我想没有关系来算,目前没有任何章节的所有书籍。

SELECT  COUNT(Id) AS Expr1 
FROM   dbo.Book 
WHERE  (Id NOT IN (SELECT BookId FROM dbo.BookChapter)) 

总是给超时过期。我怎样才能实现它?

+0

您是否在SQL Server Management Studio中获取了SQL超时值,或者您正在调用它的应用程序是否超时? – logixologist

+0

超时在sqlmanagement工作室 –

回答

4

尝试使用左加入其类似于不存在,但有时候执行得更好。

select count(1) as Counts 
from 
    dbo.Book B 
    left join dbo.BookChapter BC on BC.BookID = B.ID 
where 
    BC.BookID is null 
+0

它工作得很好。 –

+0

如果您报告所有答案的查询执行时间,那将会很有趣。如果你有章节中的bookid索引,这应该是公平的,你应该拥有这些索引。 – apartridge

+0

@apartridge上面的左连接立即显示,几乎为0ms,结果是正确的,而其他子查询在Sql管理工作室中超时到期。没有结果。 –

0

您的子查询变得非常大。您可以尝试通过BookId进行分组。

SELECT COUNT(Id) AS Expr1 
FROM dbo.Book 
WHERE (Id NOT IN (SELECT BookId FROM dbo.BookChapter GROUP BY BookId)) 

另一个选项使用NOT EXISTS;

SELECT COUNT(B.Id) AS count 
FROM dbo.Book B 
WHERE NOT EXISTS (SELECT * FROM dbo.BookChapter WHERE BookId=B.BookId)) 
+0

感谢您的及时回复。它仍然效率不高,仍然超时。 –

+0

你在'BookChapter'上有索引'BookId'吗? – apartridge

+0

哦对不起,我是新来的SQL和全文索引以及。我会尽力弄清楚。 –

0

请勿使用“不在”中。这太慢了。您可以使用“不存在”按apartidge的第二个建议,或者你可以做的完全不直观的是这样的:

select count(*) BooksWithoutChapters 
from book 
where id in 
(select id 
from book 
minus 
select bookid 
from BookChapter 
)