1

我有一个运行良好的大型查询,但是,由于我的数据库中现在的数量或记录,查询需要越来越长的时间才能完成存储过程。

首先,我很难让查询工作,而且我对自己没有信心 A)简化查询或 B)将其分解为更小的查询/存储过程。

有没有高手可以帮帮我?

SELECT 
    r.resourceFirstName, 
    r.resourceLastName,
    a.eventDateTime, 
    CONVERT(char(1), a.eventType) as eventType, 
    CONVERT(varchar(5), a.reasonCode) as reasonCode, 
    r.extension, 
    GETDATE() AS ciscoDate into #temp_Agent
FROM 
    CCX1.db_cra.dbo.Resource r 
    INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a 
        ON r.resourceID = a.agentID 
    INNER JOIN ( 
        SELECT 
            p.resourceFirstName, 
            p.resourceLastName, 
            MAX(e.eventDateTime) MaxeventDateTime 
        FROM 
            CCX1.db_cra.dbo.Resource p 
            INNER JOIN CCX1.db_cra.dbo.AgentStateDetail e 
            ON p.resourceID = e.agentID 
        where 
            e.eventDateTime > (GETDATE() - 1)
        GROUP BY 
            p.resourceFirstName, 
            p.resourceLastName
    ) d 
        ON r.resourceFirstName = d.resourceFirstName 
        AND r.resourceLastName = d.resourceLastName 
        AND a.eventDateTime = d.MaxeventDateTime 
        AND r.active = 1 
where 
    a.eventDateTime >= (GETDATE() - 7)
ORDER BY 
    r.resourceLastName,
    r.resourceFirstName ASC

4

3 回答 3

0

假设这是 SQLServer,请尝试:

WITH CTE AS
(SELECT r.resourceFirstName, 
        r.resourceLastName,
        a.eventDateTime, 
        CONVERT(char(1), a.eventType) as eventType, 
        CONVERT(varchar(5), a.reasonCode) as reasonCode, 
        r.extension, 
        GETDATE() AS ciscoDate,
        RANK() OVER (PARTITION BY r.resourceFirstName, r.resourceLastName
                     ORDER BY a.eventDateTime DESC) RN
 FROM CCX1.db_cra.dbo.Resource r 
 INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a 
         ON r.resourceID = a.agentID AND a.eventDateTime >= (GETDATE() - 1) 
 where r.active = 1)
SELECT resourceFirstName, resourceLastName, eventDateTime, eventType, reasonCode, r.extension, ciscoDate
into #temp_Agent
FROM CTE
WHERE RN=1
ORDER BY r.resourceLastName, r.resourceFirstName ASC
于 2013-02-01T19:48:59.643 回答
0

仅凭查询无法给出正确答案。但...

考虑在“eventDateTime”上放置一个索引。

您似乎在 1 天内加入了一组记录。这将使外部查询中的 7 天过滤器无关紧要。我没有能力测试,但也许您的查询可以简化为这个?(下面的伪代码)

还要考虑不同的解决方案。也许根据日期时间对表进行分区。也许有一个单独的数据库用于使用星型模式或多维数据集设计进行报告。

临时表#temp_Agent 正在做什么?

declare @max datetime = (select max(eventDateTime) 
                         from CCX1.db_cra.dbo.AgentStateDetail 
                         where active=1 
                         and eventDateTime > getdate()-1);
if(@max is null)
    exit no records today

SELECT r.resourceFirstName, 
r.resourceLastName,
a.eventDateTime, 
CONVERT(char(1), a.eventType) as eventType, 
CONVERT(varchar(5), a.reasonCode) as reasonCode, 
r.extension, 
GETDATE() AS ciscoDate 

into #temp_Agent

FROM CCX1.db_cra.dbo.Resource r 
INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a ON r.resourceID = a.agentID 

where r.active = 1 
and a.eventDateTime = @max;
于 2013-02-01T19:15:50.207 回答
0

如果没有完整的表定义,很难解决查询挂起的原因,但我给您一些提示,可以帮助您提高查询的性能:

  1. 与其使用“#temp_Agent”等临时表,不如创建“表”类型的局部变量。您可以获得完全相同的结果,但您可以大大提高性能,因为:

    • 可以使用主键和索引创建“表”类型的局部变量,从而改进 SQL 查找信息的方式。

    • 可以对局部变量进行聚类,这也提高了某些场景下的性能,因为信息是直接从磁盘访问的

    • 临时表要求 SQL 在运行时解析应该用于存储查询获得的信息的列类型。

  2. 如果您需要将信息存储在临时表、变量等中,请避免在这些变量中存储不必要的信息。例如,如果您的进程中只需要后者两个 id 列,则避免包含可以检索泡沫的额外列

  3. 如果您需要从多个来源检索大量信息,则应考虑使用视图,该视图也可以被索引并改进信息的检索。

  4. 避免使用不必要的排序、分组、转换和字符串连接。这些特定的操作会极大地降低查询的性能。

作为一个额外的提示,您可以使用旨在改进您的数据库和对象的 SQL 服务器工具:

  • 检查查询的执行计划(菜单查询->包括实际执行计划,或控制+ M)
  • 运行 SQL Server Engine Tunning Advisor 以分析跟踪文件(请参阅 SQL Server Profiler)并添加额外的索引以提高数据库性能
  • 如果您的查询没有在您用于获取信息的表中生成死锁,请使用 SQL Server Profiler 检查。在所有查询中使用“提示”以避免锁定问题和在某些情况下您希望避免的其他行为是一种很好的做法。

Se附加链接以更好地理解我的意思:

了解执行计划

提示的使用

SQL Server 中可用的调整选项

我希望这些信息有所帮助。

于 2013-02-01T19:33:18.393 回答