优化存储过程

时间:2013-02-01 17:53:00

标签: sql query-optimization

我有一个很好的查询工作,但是,由于我的数据库中现在的数字或记录,查询需要更长时间才能完成存储过程。

我有足够的时间让查询在第一时间工作,我对自己也不自信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

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

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

如果没有完整的表格定义,很难解决查询暂停的原因,但我会提供一些技巧,可以帮助您提高查询的性能:

  1. 不使用诸如“#temp_Agent”之类的临时表,而是最好创建“Table”类型的本地变量。您可以获得完全相同的结果,但您可以大幅提高性能,因为:

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

    • 可以对局部变量进行群集,这也可以改善某些情况下的性能,因为信息直接来自磁盘

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

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

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

  4. 避免使用不必要的排序,分组,转换和字符串连接。这些特定的操作cad大大降低了Query的性能。

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

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

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

    Understanding Execution Plan

    Usage of Hints

    Tunning Options available in SQL Server

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

答案 2 :(得分: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