【发布时间】:2014-02-18 15:06:11
【问题描述】:
感谢上一个问题中的所有帮助,我的项目取得了很大进展,甚至学到了很多东西。我希望能在我目前面临的性能下降问题上获得一些帮助。基本上,我们正在使用一个数据库,该数据库有一个名为“AlertHistory”的表,并且该表没有被索引(我知道,...)。我的目标是获取 AlertHistory 表中与当前 alertid 相关的最新条目。我的想法是使用外连接,但这对我们的生产服务器造成了巨大的性能损失(执行时间从大约 20 秒到大约 3 分钟)。
SELECT
AllAlerts.AlertID as AlertID,
Queues.QueueID as QueueID,
Queues.QueueName as QueueName,
AllAlerts.ConnectorID as ConnectorID,
AllAlerts.DeviceID as DeviceID,
AllAlerts.SituationMessage as Summary,
AllAlerts.AlertDetail as Detail,
AllAlerts.Acknowledged as Acknowledged,
"AcknowledgedBy" =
CASE
WHEN AllAlerts.Acknowledged = '1' THEN History.CreatedBy
WHEN AllAlerts.Acknowledged = '0' THEN ' '
END,
AllAlerts.AssignedTo as AssignedTo,
AllAlerts.ReportedTime as CreatedTime,
AllAlerts.ClearedTime as ClearedTime
from
[ISG_SOI ].[dbo].[Alerts] as AllAlerts
inner join [ISG_SOI ].[dbo].[AlertQueueAssignments] as QA
on QA.[AlertID] = AllAlerts.[AlertID]
inner join [ISG_SOI ].[dbo].[AlertQueues] AS Queues
on Queues.[QueueID] = QA.[QueueID]
outer apply (
select top 1 History.CreatedBy
from [ISG_SOI ].[dbo].[AlertHistory] as History
where History.ColumnName = '73549' and History.AlertID = AllAlerts.AlertID
order by History.CreatedTime DESC
) as History
where Queues.QueueName = 'OCC'
只是为了解释应用,ColumnName 是我需要获取的静态列。此数据库使用整数标识符 73549。当然我可以使用“声明”并声明一个变量,但我们的实现软件不支持 (BOXI)。
【问题讨论】:
-
为什么会同时标记 [mysql] 和 [tsql]?看来这是SQL-Server?你能索引这个表吗?如果不是这样,您实际上可以通过将其整体复制到临时表中,对其进行索引然后重新运行您的查询来获得更好的结果。
-
对不起,调整了标签,你是对的!不幸的是,我无法索引此表,因为它是由 BOXI 应用程序创建的表。我将不得不做一些关于复制到临时表的阅读。不确定这在性能方面如何发挥作用,因为该表可能有成千上万行。
-
您遇到的问题是,您当前的查询将一遍又一遍地扫描所有这些行,很多次。 您需要使数据结构化和可搜索。通过复制到临时表,您可以重新组织一次(对表进行一次完整扫描),然后快速搜索多次(在表上进行许多小搜索)。您越关心行数,您对数据的结构/排序/索引就越重要。 请注意,您只需复制那里的数据
where History.ColumnName = '73549',这也将节省一些时间和服务器负载。 -
您真的需要在选择中发布所有列(带有 case 和 isnull)来描述问题吗?贴出最简单的例子来重现问题。
-
@Blam 指出,谢谢,清理了原帖以便于阅读
标签: tsql sql-server-2012 business-objects