Pregunta

A principios de esta semana, formulo una pregunta sobre el filtrado de valores duplicados en secuencia en el tiempo de ejecución. Tenía algunas buenas respuestas, pero la cantidad de datos que estaba revisando era lenta y no factible.

Actualmente en nuestra base de datos, los valores de los eventos no se filtran. Resultando en valores de datos duplicados (con diferentes marcas de tiempo). Necesitamos procesar esos datos en el tiempo de ejecución y en el nivel de la base de datos, es costoso (y no podemos incluirlos en el código porque se usa mucho en procesos almacenados), lo que resulta en altos tiempos de consulta. Necesitamos una estructura de datos que podamos consultar que tenga este almacén de datos filtrado para que no se necesite filtrado adicional en tiempo de ejecución.

Actualmente en nuestra base de datos

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

Lo que necesitamos

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

Esto parece trivial, pero nuestro problema es que obtenemos estos datos de dispositivos inalámbricos, lo que resulta en paquetes fuera de secuencia y nuestra puerta de enlace es multiproceso, por lo que no podemos garantizar que los valores que obtenemos estén en orden. Algo puede aparecer como un '1' hace 4 segundos y un '0' hace 2 segundos, pero ya procesamos el '1' porque fue el primero. Hemos estado dando vueltas sobre cómo implementar esto. No podemos comparar los datos con el último valor de la base de datos porque es posible que el último aún no haya entrado, por lo que arrojar esos datos estaríamos jodidos y nuestra secuencia podría estar completamente apagada. Por lo tanto, actualmente almacenamos todos los valores que entran y la base de datos se baraja en función del tiempo ... pero las unidades pueden enviar 1,1,1,0 y es válido porque el evento todavía está activo, pero solo queremos almacenar el estado activado y desactivado (primera aparición del estado activado 1,0,1,0,1,0) ... pensamos en un activador, pero tendríamos que barajar los datos cada vez que entrara un nuevo valor porque puede ser anterior al último mensaje y puede cambiar la secuencia completa (las inserciones serían lentas).

¿Alguna idea?

Pregunte si necesita más información.

[EDITAR] PK no funcionará: el problema es que nuestras unidades realmente envían diferentes marcas de tiempo. así que el PK no funcionaría porque 1,1,1 son iguales ... pero tienen diferentes sellos de tiempo. Su evento similar se desarrolló en time1, el evento sigue activo en time2, nos envía de vuelta ambos ... el mismo valor, hora diferente.

¿Fue útil?

Solución

Aquí hay una solución de actualización. El rendimiento variará según los índices.

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

No es difícil imaginar una solución de filtrado basada en esto. Solo depende de la frecuencia con la que desee buscar el registro anterior para cada registro (cada consulta o de vez en cuando).

Otros consejos

Si entiendo correctamente, lo que quieres hacer es simplemente evitar que los falsos entren en la base de datos. Si ese es el caso, ¿por qué no tener un PK (o Índice Único) definido en las primeras dos columnas y hacer que la base de datos haga el trabajo pesado por usted? Las inserciones de Dupe fallarían según el PK o AK que haya definido. El código (o el proceso almacenado) tendría que manejar esa excepción con gracia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top