我有一个很好的查询工作,但是,由于我的数据库中现在的数字或记录,查询需要更长时间才能完成存储过程。
我有足够的时间让查询在第一时间工作,我对自己也不自信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
答案 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)
如果没有完整的表格定义,很难解决查询暂停的原因,但我会提供一些技巧,可以帮助您提高查询的性能:
不使用诸如“#temp_Agent”之类的临时表,而是最好创建“Table”类型的本地变量。您可以获得完全相同的结果,但您可以大幅提高性能,因为:
可以使用主键和索引创建“Table”类型的局部变量,从而改进SQL查找信息的方式。
可以对局部变量进行群集,这也可以改善某些情况下的性能,因为信息直接来自磁盘
临时表要求SQL在运行时解析应该用于存储查询获取的信息的列类型。
如果需要在临时表,变量等中存储信息,请避免在这些变量中存储不必要的信息。例如,如果你只需要在你的进程中使用两个id列,那么请避免包含可以检索泡沫的额外列
如果您需要从多个来源退出大量信息,则应考虑使用视图,该视图也可以编入索引并改进信息检索。
避免使用不必要的排序,分组,转换和字符串连接。这些特定的操作cad大大降低了Query的性能。
作为额外提示,您可以使用旨在改进数据库和对象的SQL服务器工具:
附上链接以更好地理解我的意思:
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