Domanda

All'inizio di questa settimana ho posto una domanda sul filtraggio di valori duplicati in sequenza in fase di esecuzione. Ho avuto delle buone risposte ma la quantità di dati che stavo esaminando era rallentare e non fattibile.

Attualmente nel nostro database, i valori degli eventi non vengono filtrati. Con conseguente valori di dati duplicati (con timestamp variabili). Dobbiamo elaborare quei dati in fase di esecuzione e a livello di database i tempi sono costosi (e non possono essere inseriti nel codice perché sono utilizzati molto nei processi archiviati) con conseguenti tempi di query elevati. Abbiamo bisogno di una struttura di dati su cui possiamo interrogare che abbia filtrato questo archivio di dati in modo che non sia necessario alcun filtro aggiuntivo in fase di esecuzione.

Attualmente nel nostro DB

  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '1', '2008-05-08 04: 03: 47.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '0', '2008-05-08 10: 02: 08.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '0', '2008-05-09 10: 03: 24.000 ’(È necessario eliminare questo) **
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '1', '2008-05-10 04: 05: 05.000'

Cosa ci serve

  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '1', '2008-05-08 04: 03: 47.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '0', '2008-05-08 10: 02: 08.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '1', '2008-05-10 04: 51: 05.000'

Sembra banale, ma il nostro problema è che otteniamo questi dati da dispositivi wireless, risultando in pacchetti fuori sequenza e il nostro gateway è multithread, quindi non possiamo garantire che i valori che otteniamo siano in ordine. Qualcosa potrebbe apparire come un '1' per 4 secondi fa e uno '0' per 2 secondi fa, ma elaboriamo '1' già perché era il primo in. Abbiamo girato la testa su come implementarlo. Non possiamo confrontare i dati con il valore più recente nel database perché l'ultimo potrebbe non essere ancora arrivato, quindi per eliminare quei dati saremmo fregati e la nostra sequenza potrebbe essere completamente fuori. Quindi al momento memorizziamo ogni valore che arriva e il database si mescola da solo in base al tempo .. ma le unità possono inviare 1,1,1,0 ed è valido perché l'evento è ancora attivo, ma vogliamo solo memorizzare il stato on e off (prima occorrenza dello stato on 1,0,1,0,1,0) .. abbiamo pensato a un trigger, ma dovremmo mescolare i dati ogni volta che entrava un nuovo valore perché potrebbe essere precedente all'ultimo messaggio e può cambiare l'intera sequenza (gli inserimenti sarebbero lenti).

Qualche idea?

Chiedi se hai bisogno di ulteriori informazioni.

[EDIT] PK Non funzionerà - il problema è che le nostre unità in realtà inviano diversi timestamp. quindi il PK non funzionerebbe perché 1,1,1 sono gli stessi .. ma ci sono diversi timestamp. Il suo evento simile è andato avanti all'ora1, l'evento è ancora acceso all'ora2, ci ha restituito entrambi .. stesso valore tempo diverso

È stato utile?

Soluzione

Ecco una soluzione di aggiornamento. Le prestazioni variano in base agli indici.

DECLARE @MyTable TABLE
(
  DeviceName varchar(100),
  EventTime DateTime,
  OnOff int,
  GoodForRead int
)

INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-08 04:03:47.000' 
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-08 10:02:08.000' 
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-09 10:03:24.000'
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-10 04:05:05.000' 

UPDATE mt
SET GoodForRead = 
CASE
  (SELECT top 1 OnOff
   FROM @MyTable mt2
   WHERE mt2.DeviceName = mt.DeviceName
     and mt2.EventTime < mt.EventTime
   ORDER BY mt2.EventTime desc
  )
  WHEN null THEN 1
  WHEN mt.OnOff THEN 0
  ELSE 1
END
FROM @MyTable mt
    -- Limit the update to recent data
--WHERE EventTime >= DateAdd(dd, -1, GetDate())

SELECT *
FROM @MyTable

Non è difficile immaginare una soluzione di filtraggio basata su questo. Dipende solo da quanto spesso vuoi cercare il record precedente per ogni record (ogni query o una volta ogni tanto).

Altri suggerimenti

Se ho capito bene, quello che vuoi fare è semplicemente impedire ai duplicati di entrare nel database. In tal caso, perché non avere un PK (o un indice univoco) definito nelle prime due colonne e fare in modo che il database esegua il lavoro pesante per te. Inserimenti duplicati fallirebbero in base al PK o AK che hai definito. Il tuo codice (o stored procedure) dovrebbe solo gestire con garbo quell'eccezione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top