优化 sql 计数查询
Posted
技术标签:
【中文标题】优化 sql 计数查询【英文标题】:Optomizing a sql Count Query 【发布时间】:2010-07-15 15:23:29 【问题描述】:我对 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 运行的。
编辑—— 作为询问它的所有答案,我检查了它。 accountid 升序时的 Opportunity 和票证索引。
【问题讨论】:
是的,尤其是在处理制表符时,格式有时会有些棘手和“随机” :-) 很高兴知道您了解正确的格式 - 对可读性有很大影响! 【参考方案1】:我认为下面的内容在逻辑上应该是等效的并且更有效。显然测试这两个方面你的目的!
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 上是否存在索引并且正在使用。
【讨论】:
索引确实存在,我在执行计划上找什么看是否在使用? @Scott - 主要要看的是昂贵的运营商实际上是什么。您已经更新了您的问题,说您有索引,但只需 3-5 秒即可提取大约 20 条记录,这听起来比在这种情况下预期的要多。你试过我的查询吗?【参考方案2】:SQL 引擎(即使在 2000 年)已经足够聪明,可以优化该 sql。根据你的性能数据和这么少的结果,我猜源数据有一堆记录并且没有 sql 需要的索引。
确保 Opportunity.AccountID 上有一个索引,Ticket.AccountID 上有一个索引。
【讨论】:
我同意你的索引。不太相信 SQL2000 会像你说的那样优化它。以上是关于优化 sql 计数查询的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server SQL性能优化之--pivot行列转换减少扫描计数优化查询语句
如何优化执行嵌套在 group-by 子句中的计数的 SQL 查询?