2010-07-15 58 views
0

我对SQL仍然相当陌生,所以我想知道如果我正在做这个最优化的方式。Optomizing sql计数查询

SELECT DISTINCT ACCOUNTID, ACCOUNT_NAME 
    (SELECT  COUNT(*) 
    FROM   TICKET 
    WHERE  (ACCOUNTID = OPPORTUNITY.ACCOUNTID)) AS [Number Of Tickets], 
    (SELECT  COUNT(*) 
    FROM   TICKET 
    WHERE  (ACCOUNTID = OPPORTUNITY.ACCOUNTID) AND (STATUSCODE = 1 OR 
     STATUSCODE = 2 OR 
     STATUSCODE = 3)) AS [Active Tickets] 
from OPPORTUNITY 
    where AccountID > @LowerBound and AccountID < @UpperBound 

我所试图做的就是让所有账户的清单,并把它显示帐户多少张门票有多少是有效的(有一个状态代码为1,2,或3)。选择内部选择正确的方式来做到这一点,或者是否有一种方法可以使用类似group by的方法来完成。

我最大的担忧是速度,只需拉动20条记录需要3-5秒,查询可能会有1000条结果。

我不是DBA,所以表格模式的任何改变都不是强制性的,但需要一些上层管理者的恳求。

这是正在针对SQL Server 2000

EDIT-- 所有地方问它,我就可以检查答案的运行。按升序排列的机会和机票指数。

+0

是的,格式化特别是在处理标签页时有点棘手和有时是“随机的”:-)很高兴知道您了解正确的格式 - 为可读性做出巨大改变! – 2010-07-15 15:49:41

回答

2

我认为下面应该在逻辑上等效并且更高效。很明显,测试两方面你的结局!

SELECT O.ACCOUNTID, O.ACCOUNT_NAME, 
    COUNT(*) AS [Number Of Tickets], 
    ISNULL(SUM(CASE WHEN STATUSCODE IN (1,2,3) THEN 1 ELSE 0 END),0) 
                   AS [Active Tickets] 
FROM OPPORTUNITY O 
LEFT OUTER JOIN TICKET T ON T.ACCOUNTID = O.ACCOUNTID 
    WHERE O.ACCOUNTID > @LowerBound and O.ACCOUNTID < @UpperBound 
    GROUP BY O.ACCOUNTID, O.ACCOUNT_NAME 

如果您可以查看执行计划,那么您应该检查两个表中ACCOUNTID上存在的索引并且正在使用。

+0

索引确实存在,我在执行计划中寻找它是否正在使用它? – 2010-07-15 15:55:15

+0

@Scott - 要看的主要是昂贵的操作员实际上是什么。你已经更新了你的问题,说你已经有了索引,但是只需要3-5秒就可以获得20个以上的记录。你试过我的查询吗? – 2010-07-15 15:59:42

1

SQL引擎(即使在2000年)足够聪明,可以优化该sql。根据你的性能数据和这么少的结果,我猜测源数据有一堆记录,并没有sql需要的索引。

确保在Opportunity.AccountID上有一个索引,并在Ticket.AccountID上有一个索引。

+0

我同意你的指标。不太确信SQL2000会像你说的那样优化它。 – 2010-07-15 15:40:17