2011-10-17 75 views
1

我有一个表,看起来像这样(我不知道,什么都可能是相关的,所以我不得不蟾蜍转储整个结构)SQL Server 2005的查询与子查询的最大

CREATE TABLE [dbo].[TScore] (
[CustomerID] int NOT NULL, 
[ApplNo] numeric(18, 0) NOT NULL, 
[BScore] int NULL, 
[OrigAmt] money NULL, 
[MaxAmt] money NULL, 
[DateCreated] datetime NULL, 
[UserCreated] char(8) NULL, 
[DateModified] datetime NULL, 
[UserModified] char(8) NULL, 
CONSTRAINT [PK_TScore] 
PRIMARY KEY CLUSTERED ([CustomerID] ASC, [ApplNo] ASC) 
); 

和优化当我运行以下查询时(在TScore表中有300万条记录的数据库上),即使如果我这样做:Select BScore from CustomerDB..TScore WHERE CustomerID = 12345,它是即时的(并且只返回10条记录),似乎需要大约一秒钟的时间应该有一些有效的方法来在单个查询中执行Max(ApplNo)效果,但我是SQL Server的相对技术人员,但并不确定 - 我想我可能需要ApplNo的单独密钥,但不知道如何聚集钥匙工作。

SELECT BScore 
FROM CustomerDB..TScore (NOLOCK) 
WHERE ApplNo = (SELECT Max(ApplNo) 
       FROM CustomerDB..TScore sc2 (NOLOCK) 
       WHERE sc2.CustomerID = 12345) 

感谢任何提示(在哪里找的SQL服务器上的东西优化指针赞赏和)

回答

4

当您ApplNo筛选,您使用的是关键的一部分。而不是左手边。这意味着索引已被扫描(查看所有行),而不是查找(钻取到一行)以查找值。

  • 如果你正在寻找相同的客户ID ApplNo值:

快捷方式。使用完整的聚集索引:

SELECT BScore 
FROM CustomerDB..TScore 
WHERE ApplNo = (SELECT Max(ApplNo) 
       FROM CustomerDB..TScore sc2 
       WHERE sc2.CustomerID = 12345) 
AND CustomerID = 12345 

这可以变成一个JOIN

SELECT BScore 
FROM 
    CustomerDB..TScore T1 
    JOIN 
    (SELECT Max(ApplNo) AS MaxApplNo, CustomerID 
     FROM CustomerDB..TScore sc2 
     WHERE sc2.CustomerID = 12345 
    ) T2 ON T1.CustomerID = T2.CustomerID AND T1.ApplNo= T2.MaxApplNo 
  • 如果您正在寻找独立的客户ID的ApplNo值,那么我会看一个单独的索引。这符合你当前的代码

CREATE INDEX IX_ApplNo ON TScore (ApplNo) INCLUDE (BScore);

扭转键顺序不会帮助,因为那么你WHERE sc2.CustomerID = 12345将扫描的意图,而不是寻求

注意:在使用NOLOCK到处都是不好的做法

+0

非常感谢您的帮助 - 对于NOLOCK小贴士 - 目前在任何地方都可以使用它,并且在我开始这项工作时,我专门告诉我在任何地方都会使用它,因此需要一点工作才能说服别人 - 关于p。的文章的任何提示特别好呢? (我搜索了一下,发现了一对看起来很合理的对象,只要你知道任何特别好的答案就回复) –

+0

只需搜索上面的“user:27535 nolock” – gbn