0

我有一个带有设备的表,还有一个带有性能计数器的表。所以我有设备 A,可以说性能计数器表中有 1000 个条目。我正在尝试获取所有设备,其中 2500 台,以及它们最近的性能计数器。我使用了 Outer Apply,它确实实现了预期的结果,但查询需要 5 分钟才能执行。

这是获取我正在寻找的信息的最佳方式还是有更好的方式?这个查询的性能是否正常,我只是要求太多了?我正在考虑每晚创建第三个“临时”表来保存这些数据,以便我可以快速显示和查询信息。这样的最佳实践是什么?

这是我当前的查询:

   select * from Device D
      OUTER APPLY
          ( select top 1 *
              FROM PerformanceCounterValues
              where instance_id = D.pkid
              order by collection_time desc
           ) as tbl2

- - - 解决了 - -

这是我最后的实际查询,它在 0 秒内工作。

SELECT pkid, D.IDDevice, D.IDHardware, H.IDRecorder, D.Name, D.Description, H.Name as HardwareName, H.URI, R.HostName, R.Name as RecorderInstance, tbl2.collection_time, tbl2.raw_value, tbl2.calculated_value
  FROM [Surveillance].[dbo].[PerformanceCounterInstance] PCI
  JOIN [Surveillance].[dbo].[Devices] D on D.IDDevice = (SELECT REPLACE(STUFF([instance_name],1,CHARINDEX('[',[instance_name]),''),']',''))
  JOIN [Surveillance].[dbo].[Hardware] H on H.IDHardware = D.IDHardware
  JOIN [Surveillance].[dbo].[Recorders] R on R.IDRecorder = H.IDRecorder
    OUTER APPLY
    ( select top 1 *
        FROM [Surveillance].[dbo].[PerformanceCounterValue]
        where instance_id = PCI.pkid
        order by collection_time desc
        ) as tbl2
  where category_name = 'VideoOS Recording Server Device Storage'
  and D.Enabled = 1

只是设置了使速度增加的索引。

4

4 回答 4

1

尝试

  select D.pkid, max(PerformanceCounterValues.collection_time)
  from Device D
  join PerformanceCounterValues
  on  PerformanceCounterValues.instance_id = D.pkid 
  group by D.pkid
于 2012-08-07T16:53:48.073 回答
1

我不确定什么索引最适合outer apply查询,但您可以尝试(instance_id, collection_time)为此添加索引:

   SELECT 
        d.*                --- whatever columns you need from Device 
      , p.*                --- and from PerformanceCounterValues
   FROM Device AS d
     JOIN
       ( SELECT instance_id, 
                MAX(collection_time) AS max_collection_time
         FROM PerformanceCounterValues
         GROUP BY instance_id
       ) AS grp
       ON  grp.instance_id = d.pkid
     JOIN PerformanceCounterValues AS p
       ON  p.instance_id = grp.instance_id 
       AND p.collection_time = grp.max_collection_time ;

如果您在问题中添加查询的执行计划也会有所帮助。

于 2012-08-07T17:53:43.830 回答
0

尝试直接在连接上选择前一个,我在一个表中有大约 20,000 个相应的条目,我想从日志表中获取第一个条目时间。我的查询在 2 秒内执行(MsSql 2008)

select D.pkid, pvc.*
from Device D
join PerformanceCounterValues as pcv on pcv.PrimaryKey = (SELECT top(1) PrimaryKey From      PerformanceCounterValues WHERE instance_id = D.pkid ORDER BY collection_time )
于 2012-08-07T17:26:48.993 回答
0

启用索引并使用此查询:

SELECT pkid, D.IDDevice, D.IDHardware, H.IDRecorder, D.Name, D.Description, H.Name as HardwareName, H.URI, R.HostName, R.Name as RecorderInstance, tbl2.collection_time, tbl2.raw_value, tbl2.calculated_value
  FROM [Surveillance].[dbo].[PerformanceCounterInstance] PCI
  JOIN [Surveillance].[dbo].[Devices] D on D.IDDevice = (SELECT REPLACE(STUFF([instance_name],1,CHARINDEX('[',[instance_name]),''),']',''))
  JOIN [Surveillance].[dbo].[Hardware] H on H.IDHardware = D.IDHardware
  JOIN [Surveillance].[dbo].[Recorders] R on R.IDRecorder = H.IDRecorder
    OUTER APPLY
    ( select top 1 *
        FROM [Surveillance].[dbo].[PerformanceCounterValue]
        where instance_id = PCI.pkid
        order by collection_time desc
        ) as tbl2
  where category_name = 'VideoOS Recording Server Device Storage'
  and D.Enabled = 1
于 2012-10-29T15:13:51.887 回答