0

SQL 2000を使用しています。複雑な一連の基準に基づいて不要な重複をすべて削除できるようになりましたが、クエリの取得に約3.5分しかかからなかったため、クエリの完了に数時間かかるようになりました。重複を含むデータ。

明確にするために:rpt.HostNameフィールドまたはrpt.SystemSerialNumberフィールドのいずれかが異なる限り、重複するrpt.Nameフィールドを持つことができます。また、4つの異なる列の一部にはタイムスタンプがないため、4つの異なる列のタイムスタンプに基づいて保持するエントリを決定する必要があります。

どんな助けでも大歓迎です!

SELECT 
rpt.[Name],
rpt.LastAgentExecution,
rpt.GroupName,
rpt.PackageName,
rpt.PackageVersion,
rpt.ProcedureName,
rpt.HostName,
rpt.SystemSerialNumber,
rpt.JobCreationTime,
rpt.JobActivationTime,
rpt.[Job Completion Time]
FROM DSM_StandardGroupMembersProcedureActivityViewExt rpt
WHERE
(
  (
      rpt.GroupName = 'Adobe Acrobat 7 Deploy'
   OR rpt.GroupName = 'Adobe Acrobat 8 Deploy'
  )
  AND
  (
      (rpt.PackageName = 'Adobe Acrobat 7' AND rpt.PackageVersion = '-1.0')
   OR (rpt.PackageName = 'Adobe Acrobat 8' AND rpt.PackageVersion = '-3.0')
  )
)
AND NOT EXISTS
(
  SELECT *
  FROM   DSM_StandardGroupMembersProcedureActivityViewExt rpt_dupe
  WHERE
  (
    (
     rpt.GroupName = 'Adobe Acrobat 7 Deploy'
      OR rpt.GroupName = 'Adobe Acrobat 8 Deploy'
    )
    AND
    (
     (rpt.PackageName = 'Adobe Acrobat 7' AND rpt.PackageVersion = '-1.0')
      OR (rpt.PackageName = 'Adobe Acrobat 8' AND rpt.PackageVersion = '-3.0')
    )
    AND
    (
      (rpt_dupe.[Name] = rpt.[Name])
      AND
      (
       (rpt_dupe.SystemSerialNumber = rpt.SystemSerialNumber)
    OR (rpt_dupe.HostName = rpt.HostName)
      )
      AND
      (
       (rpt_dupe.LastAgentExecution    < rpt.LastAgentExecution)
    OR (rpt_dupe.JobActivationTime     < rpt.JobActivationTime)
    OR (rpt_dupe.JobCreationTime       < rpt.JobCreationTime)
    OR (rpt_dupe.[Job Completion Time] < rpt.[Job Completion Time])
      )
    )
  )
)
4

2 に答える 2

0

その理由は not exists 句です。

これを左外部結合として書き直すことをお勧めします。

 from <big query> left outer join
      <dups query>
      on <all the fields that constitute a match>
 where <dups query>.<some field> is null

存在しないことがわかり、最適化が不十分なことがよくあります。

もう 1 つの提案は、このクエリをより直接的な実装に変更することです。

with t as (
    SELECT rpt.[Name], rpt.LastAgentExecution, rpt.GroupName, rpt.PackageName,
           rpt.PackageVersion, rpt.ProcedureName, rpt.HostName, rpt.SystemSerialNumber, 
            rpt.JobCreationTime, rpt.JobActivationTime, rpt.[Job Completion Time]
    FROM DSM_StandardGroupMembersProcedureActivityViewExt rpt
    WHERE rpt.GroupName in ('Adobe Acrobat 7 Deploy', 'Adobe Acrobat 8 Deploy') AND
          ((rpt.PackageName = 'Adobe Acrobat 7' AND rpt.PackageVersion = '-1.0') OR
           (rpt.PackageName = 'Adobe Acrobat 8' AND rpt.PackageVersion = '-3.0')
          )
 )
 select t.*
 from t join
      (select name, ..., max(id)
       from t
       group by name, ...
      ) tsum
      on t.id = tsum.id

つまり、区別したい列ごとにテーブルを要約します。行の 1 つを選択します。ここでは、各行を一意に識別するための「id」フィールドがあると想定しています。名前や日付など、フィールドの組み合わせを使用する必要がある場合があります。ID がないと、これはより困難になります。最近のバージョンの SQL サーバーでは、row_number() を使用できます。

于 2012-05-11T00:53:17.553 に答える
0

それらの線に沿って試してください:

SELECT t_main.columns
FROM table as t_main
LEFT JOIN 
(
SELECT name, MAX(lastAgentExecution)..... FROM table GROUP BY name,serialnumber, hostname
)
as t_joinSerial
ON t_main.name=t_joinSerial.name,lastAgentExecution etc.
where (t_main.AdobeStuff and t_joinSerial is NULL)
于 2012-05-10T23:43:29.567 に答える