Question

Plus tôt cette semaine, j'ai posé une question sur le filtrage des valeurs en double en séquence au moment de l'exécution. Avait de bonnes réponses, mais la quantité de données que je revenais était trop lente et impossible.

Actuellement dans notre base de données, les valeurs d'événement ne sont pas filtrées. Résultat: des valeurs de données en double (avec des horodatages variables). Nous devons traiter ces données au moment de l’exécution et au niveau de la base de données, cela prend du temps (et ne peut pas les extraire dans le code car elles ont beaucoup utilisé dans les processus stockés), ce qui entraîne des temps d’interrogation élevés. Nous avons besoin d'une structure de données sur laquelle nous pouvons interroger et qui a ce magasin de données filtré afin qu'aucun filtrage supplémentaire ne soit nécessaire au moment de l'exécution.

Actuellement dans notre base de données

  • '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' (Besoin de le supprimer) **
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '1', '2008-05-10 04: 05: 05.000'

Ce dont nous avons besoin

  • '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'

Cela semble anodin, mais notre problème est que nous obtenons ces données à partir d’appareils sans fil, ce qui entraîne des paquets hors séquence et que notre passerelle est multithread, nous ne pouvons donc pas garantir que les valeurs que nous obtenons sont en ordre. Quelque chose peut arriver comme un "1" il y a 4 secondes et un "0" il y a 2 secondes, mais nous traitons déjà le "1" parce que c'était le premier arrivé. Nous avons réfléchi à la manière de le mettre en œuvre. Nous ne pouvons pas comparer les données à la dernière valeur de la base de données, car les dernières peuvent ne pas encore être entrées. Par conséquent, si vous jetez ces données, nous serions foutus et notre séquence risque d'être complètement fausse. Donc, actuellement, nous stockons chaque valeur qui entre et la base de données se mélange en fonction du temps .. mais les unités peuvent envoyer 1,1,1,0 et sa valeur est valide car l'événement est toujours actif, mais nous souhaitons uniquement stocker le fichier. état activé et désactivé (première occurrence de l'état activé 1,0,1,0,1,0) .. nous avons pensé à un déclencheur, mais nous devrions mélanger les données chaque fois qu'une nouvelle valeur est entrée car elle peut être plus tôt que le dernier message et cela peut changer la séquence entière (les insertions seraient lentes).

Des idées?

Demandez si vous avez besoin d'informations supplémentaires.

[EDIT] PK Ne fonctionnera pas - le problème est que nos unités envoient en fait des horodatages différents. donc le PK ne fonctionnerait pas parce que 1,1,1 sont les mêmes .. mais il y a différents horodatages. Son événement similaire s’est déroulé à heure1, événement toujours à heure2, il nous renvoie les deux .. même valeur, heure différente.

Était-ce utile?

La solution

Voici une solution de mise à jour. Les performances varient en fonction des index.

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

Il n’est pas difficile d’imaginer une solution de filtrage basée sur cela. Tout dépend de la fréquence à laquelle vous souhaitez rechercher l'enregistrement précédent pour chaque enregistrement (chaque requête ou de temps en temps).

Autres conseils

Si je comprends bien, vous voulez simplement empêcher les dupes de pénétrer dans la base de données. Si tel est le cas, pourquoi ne pas définir un PK (ou un index unique) sur les deux premières colonnes et laisser la base de données se charger de tout. Les inserts Dupe échoueraient en fonction du PK ou de l'AK que vous avez défini. Votre code (ou procédure stockée) devrait alors gérer cette exception avec élégance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top