2010-07-15 90 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