0

デバイスを含むテーブルと、パフォーマンス カウンターを含む 2 つ目のテーブルがあります。したがって、デバイス A には、パフォーマンス カウンター テーブルに 1000 のエントリがあるとします。すべてのデバイス、2500 台のデバイス、およびそれらの最新のパフォーマンス カウンターを取得しようとしています。Outer Apply を使用しましたが、これで目的の結果が得られましたが、クエリの実行に 5 分かかりました。

これは私が探している情報を取得するための最良の方法ですか、それとももっと良い方法がありますか? このクエリのパフォーマンスは正常ですか?質問が多すぎますか? このデータを保持する 3 番目の「一時」テーブルを夜間に作成して、情報をすばやく表示およびクエリできるようにすることを考えています。このようなもののベストプラクティスは何ですか?

これが私の現在のクエリです:

   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

クエリにどのインデックスが最適かはわかりません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 に答える
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 に答える
0

結合で一番上のものを直接選択してみてください。ログテーブルから最初のエントリ時間を取得したい 1 つのタルベに約 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 に答える