Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Temukan total waktu bekerja dengan banyak pekerjaan / pesanan dengan waktu tumpang tindih / tumpang tindih pada setiap pekerja dan pekerjaan / pesanan

Kueri ini juga berfungsi. Performanya sangat bagus (sementara rencana eksekusi terlihat tidak terlalu bagus, CPU dan IO sebenarnya mengalahkan banyak kueri lainnya).

Lihat itu bekerja di Sql Fiddle .

WITH Times AS (
   SELECT DISTINCT
      H.WorkerID,
      T.Boundary
   FROM
      dbo.JobHistory H
      CROSS APPLY (VALUES (H.JobStart), (H.JobEnd)) T (Boundary)
), Groups AS (
   SELECT
      WorkerID,
      T.Boundary,
      Grp = Row_Number() OVER (PARTITION BY T.WorkerID ORDER BY T.Boundary) / 2
   FROM
      Times T
      CROSS JOIN (VALUES (1), (1)) X (Dup)
), Boundaries AS (
   SELECT
      G.WorkerID,
      TimeStart = Min(Boundary),
      TimeEnd = Max(Boundary)
   FROM
      Groups G
   GROUP BY
      G.WorkerID,
      G.Grp
   HAVING
      Count(*) = 2
)
SELECT
   B.WorkerID,
   WorkedMinutes = Sum(DateDiff(minute, 0, B.TimeEnd - B.TimeStart))
FROM
   Boundaries B
WHERE
   EXISTS (
      SELECT *
      FROM dbo.JobHistory H
      WHERE
         B.WorkerID = H.WorkerID
         AND B.TimeStart < H.JobEnd
         AND B.TimeEnd > H.JobStart
   )
GROUP BY
   WorkerID
;

Dengan indeks berkerumun di WorkerID, JobStart, JobEnd, JobID , dan dengan sampel 7 baris dari biola di atas, templat untuk data pekerja/pekerjaan baru yang diulang cukup lama untuk menghasilkan tabel dengan 14.336 baris, berikut adalah hasil kinerjanya. Saya telah menyertakan jawaban lain yang berfungsi/benar di halaman (sejauh ini):

Author  CPU  Elapsed  Reads   Scans
------  ---  -------  ------  -----
  Erik  157    166      122       2
Gordon  375    378    106964  53251

Saya melakukan pengujian yang lebih lengkap dari server yang berbeda (lebih lambat) (di mana setiap kueri dijalankan 25 kali, nilai terbaik dan terburuk untuk setiap metrik dibuang, dan 23 nilai sisanya dirata-ratakan) dan mendapatkan yang berikut:

Query     CPU   Duration  Reads   Notes
--------  ----  --------  ------  ----------------------------------
Erik 1    215   231       122     query as above
Erik 2    326   379       116     alternate technique with no EXISTS
Gordon 1  578   682       106847  from j
Gordon 2  584   673       106847  from dbo.JobHistory

Teknik alternatif yang saya pikir pasti untuk memperbaiki keadaan. Yah, itu menghemat 6 bacaan, tetapi membutuhkan lebih banyak CPU (yang masuk akal). Daripada melanjutkan statistik awal/akhir setiap timelice sampai akhir, yang terbaik adalah menghitung ulang slice mana yang harus disimpan dengan EXISTS terhadap data aslinya. Mungkin profil yang berbeda dari beberapa pekerja dengan banyak pekerjaan dapat mengubah statistik kinerja untuk kueri yang berbeda.

Jika ada yang ingin mencobanya, gunakan CREATE TABLE dan INSERT pernyataan dari biola saya dan kemudian jalankan ini 11 kali:

INSERT dbo.JobHistory
SELECT
   H.JobID + A.MaxJobID,
   H.WorkerID + A.WorkerCount,
   DateAdd(minute, Elapsed + 45, JobStart),
   DateAdd(minute, Elapsed + 45, JobEnd)
FROM
   dbo.JobHistory H
   CROSS JOIN (
      SELECT
         MaxJobID = Max(JobID),
         WorkerCount = Max(WorkerID) - Min(WorkerID) + 1,
         Elapsed = DateDiff(minute, Min(JobStart), Min(JobEnd))
      FROM dbo.JobHistory
   ) A
;

Saya membangun dua solusi lain untuk kueri ini tetapi yang terbaik dengan kinerja sekitar dua kali lipat memiliki kelemahan fatal (tidak menangani rentang waktu yang tertutup sepenuhnya dengan benar). Yang lain memiliki statistik yang sangat tinggi/buruk (yang saya tahu tetapi harus dicoba).

Penjelasan

Dengan menggunakan semua waktu titik akhir dari setiap baris, buat daftar yang berbeda dari semua rentang waktu yang mungkin menarik dengan menduplikasi setiap waktu titik akhir dan kemudian mengelompokkan sedemikian rupa untuk memasangkan setiap waktu dengan waktu berikutnya yang memungkinkan. Jumlahkan menit yang telah berlalu dari rentang ini di mana pun bertepatan dengan waktu kerja pekerja yang sebenarnya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ketergantungan SQL Server

  2. Simpan File di SQL Server atau simpan di File Server?

  3. SQL Server Terjadi operasi floating point yang tidak valid

  4. Bagaimana cara langsung mengeksekusi kueri SQL di C #?

  5. Kesalahan dalam SQL Dinamis SP