Pregunta

He mirado por todas partes y todavía no han encontrado una manera inteligente para manejar esto, aunque me siento seguro de que uno es posible:

Una tabla de datos históricos tiene información trimestral:

CREATE TABLE Quarterly (
unique_ID INT UNSIGNED NOT NULL,
date_posted DATE NOT NULL,
datasource TINYINT UNSIGNED NOT NULL,
data FLOAT NOT NULL,
PRIMARY KEY (unique_ID));

Otra tabla de datos históricos (que es muy grande) contiene información diaria:

CREATE TABLE Daily (
unique_ID INT UNSIGNED NOT NULL,
date_posted DATE NOT NULL,
datasource TINYINT UNSIGNED NOT NULL,
data FLOAT NOT NULL,
qtr_ID INT UNSIGNED,
PRIMARY KEY (unique_ID));

El campo qtr_ID no es parte de la alimentación de los datos diarios que poblaron la base de datos - en su lugar, lo que necesito para poblar el campo retroactivamente qtr_ID en la tabla diaria con la fila ID Quarterly.unique_ID, con lo que habría sido el más reciente datos trimestrales sobre Daily.date_posted que para esa fuente de datos.

Por ejemplo, si los datos trimestral es

  

101 2009-03-31 1 4.5
   102 2009-06-30 1 4,4
   103 2009-03-31 2 7,6
   2009-06-30 104 2 7,7
   105 2009-09-30 1 4,7

y los datos diarios es

  

1001 2009-07-14 1 3,5 ??
  1002 2009-07-15 1 3.4 &&
  1003 2009-07-14 2 2,3 ^^

A continuación, nos gustaría que el ?? qtr_ID campo que se asignará '102' como el barrio más reciente para esa fuente de datos en esa fecha, y también sería && '102', y sería ^^ '104'.

Los desafíos incluyen que las dos tablas (en particular la mesa diaria) son en realidad muy grande, que no pueden ser normalizados para deshacerse de las fechas repetitivas o de otro modo optimizado, y para ciertas entradas diarias no hay ninguna entrada trimestral anterior.

He probado una gran variedad de combinaciones, utilizando datediff (donde el desafío es encontrar el valor mínimo de datediff mayor que cero), y otros intentos, pero nada está trabajando para mí - por lo general mi sintaxis es romper alguna parte. dan la bienvenida cualquier idea - Voy a ejecutar cualquier ideas o conceptos básicos y posterior informe

.
¿Fue útil?

Solución

Sólo subconsulta para la Identificación del cuarto usando algo como:

(
 SELECT unique_ID 
 FROM Quarterly 
 WHERE 
     datasource = ? 
     AND date_posted >= ? 
 ORDER BY
     unique_ID ASC
 LIMIT 1
)

Por supuesto, esto probablemente no le dará el mejor rendimiento, y se asume que las fechas se añaden a trimestral secuencial (de lo contrario order by date_posted). Sin embargo, debe resolver su problema.

Se utilizaría esta subconsulta en sus INSERT o UPDATE exposiciones que el valor de su campo qtr_ID para su mesa Daily.

Otros consejos

Los siguientes parece funcionar exactamente como se pretende, pero sin duda es feo (con tres llamadas a la misma DATEDIFF !!), tal vez viendo una consulta a alguien que trabaje podría ser capaz de reducir aún más o mejorarlo:

UPDATE Daily SET qtr_ID = (select unique_ID from Quarterly
WHERE Quarterly.datasource = Daily.datasource AND
DATEDIFF(Daily.date_posted, Quarterly.date_posted) = 
(SELECT MIN(DATEDIFF(Daily.date_posted, Quarterly.date_posted)) from Quarterly
WHERE Quarterly.datasource = Daily.datasource AND
DATEDIFF(Daily.date_posted, Quarterly.date_posted) > 0));

Después de más trabajo en esta consulta, que terminó con enormes mejoras de rendimiento sobre el concepto original. La mejora más importante fue la creación de índices, tanto en las tablas diarias y trimestrales - en el diario creé índices de (fuente de datos, date_posted) y (date_posted, fuente de datos) USO BTREE y en (fuente de datos) USING HASH, y en Trimestral Hice lo mismo cosa. Esta es una exageración, pero se aseguró de que tenía una opción que el motor de consulta podría utilizar. Eso redujo el tiempo de consulta a menos del 1% de lo que había sido. (!!)

A continuación, he aprendido que dado mis circunstancias particulares que podría utilizar MAX () en lugar de ORDER BY y LIMIT lo que utilizar una llamada a MAX () para obtener el UNIQUE_ID apropiado. Eso redujo el tiempo de consulta en un 20%.

Por último, he aprendido que con el motor de almacenamiento InnoDB pude segmento de la parte de la mesa diaria que estaba poniendo al día con cualquier consulta, lo que me permitió a la multi-hilo de las consultas con un poco de codo grasa y secuencias de comandos. El procesamiento en paralelo funcionó bien y cada hilo redujo el tiempo de consulta linealmente.

Por lo tanto, la consulta básica que está realizando literalmente 1000 veces mejor que la mía primer intento es:

UPDATE Daily
SET qtr_ID =
(
  SELECT MAX(unique_ID)
  FROM Quarterly
  WHERE Daily.datasource = Quarterly.datasource AND
        Daily.date_posted > Quarterly.dateposted
)
WHERE unique_ID > ScriptVarLowerBound AND
      unique_ID <= ScriptVarHigherBound
;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top