una - unir dos tablas sql server
¿Cómo unir dos tablas basadas en una marca de tiempo(con una variación de algunos segundos)? (1)
Tengo dos tablas a las que intento unir e insertar en otra tabla basada en una combinación de tres columnas. Lo explicaré.
Tabla M
| ANO | BNO | Timestamp | Duration
---------------------------------------------------------------
| 5612853 | 4732621 | 21.11.2013 09:50:58 | 196
| 4842988 | 5610953 | 21.11.2013 17:34:58 | 98
| 7765759 | 5612853 | 21.11.2013 20:48:00 | 377
| 2470321 | 2470263 | 21.11.2013 21:47:18 | 125
Tabla N
| ANO | BNO | Timestamp | Duration
---------------------------------------------------------------
| 5612853 | 4732621 | 21.11.2013 09:50:52 | 196
| 4842988 | 5610953 | 21.11.2013 17:34:53 | 98
| 7765759 | 5612853 | 21.11.2013 20:47:55 | 377
| 2470321 | 2470263 | 21.11.2013 21:47:13 | 125
Ahora estas dos tablas tienen que coincidir e insertarse en la Tabla MN en función de
M.ANO=N.ANO and M.BNO=N.BNO and ((M.TIMESTAMP = N.TIMESTAMP+5/86400) or (M.TIMESTAMP = N.TIMESTAMP+6/86400))
Entonces, en teoría, mi salida Table MN debería ser
| ANO | BNO | Timestamp | Duration || ANO | BNO | Timestamp | Duration
--------------------------------------------------------------------------------------------------------------
| 5612853 | 4732621 | 21.11.2013 09:50:58 | 196 || 5612853 | 4732621 | 21.11.2013 09:50:52 | 196
| 4842988 | 5610953 | 21.11.2013 17:34:58 | 98 || 4842988 | 5610953 | 21.11.2013 17:34:53 | 98
| 7765759 | 5612853 | 21.11.2013 20:48:00 | 377 || 7765759 | 5612853 | 21.11.2013 20:47:55 | 377
| 2470321 | 2470263 | 21.11.2013 21:47:18 | 125 || 2470321 | 2470263 | 21.11.2013 21:47:13 | 125
La Tabla M tiene alrededor de 1.4 millones de registros, y la Tabla N tiene alrededor de 0.9 millones.
Intenté unir las dos tablas en función de las dos consultas siguientes. Pero lleva horas ejecutarlo y eso no es factible si tengo que ejecutar esto diariamente.
INSERT INTO MN_RECON (
SELECT M.*,N.* FROM M FULL OUTER JOIN N ON
M.ANO=N.ANO AND M.BNO=N.BNO AND
((M.TIMESTAMP=N.TIMESTAMP+5/86400) OR (M.TIMESTAMP=N.TIMESTAMP+6/86400))
INSERT INTO MN_RECON (
SELECT M.*,N.* FROM M FULL OUTER JOIN N ON
M.ANO=N.ANO AND M.BNO=N.BNO AND
(M.TIMESTAMP-N.TIMESTAMP IN (5/86400,6/86400)
Cuando ejecuto solo la instrucción SELECT de las 2 consultas anteriores, obtengo una salida en un minuto (solo unas 100 líneas de muestra) pero con el INSERT agregado lleva mucho tiempo. ¿Hay alguna manera de optimizar lo que quiero hacer?
Necesito que coincida con la marca de tiempo porque puede haber varias ocurrencias de la misma combinación ANO - BNO durante el día, con la marca de tiempo como el único identificador entre ellas
Y necesito una combinación externa completa porque necesito centrarme en los registros que no coinciden, así como los registros coincidentes con una diferencia de duración entre las dos tablas.
Información adicional de Oracle Oracle Database 11g Enterprise Edition 11.2.0.3.0 Producción de 64 bits
EXPLIQUE EL PLAN
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 2386K| 530M| | 2395M (1)|999:59:59 |
| 1 | LOAD TABLE CONVENTIONAL | MN_RECON | | | | | |
| 2 | VIEW | | 2386K| 530M| | 2395M (1)|999:59:59 |
| 3 | UNION-ALL | | | | | | |
|* 4 | HASH JOIN RIGHT OUTER| | 1417K| 109M| 49M| 10143 (1)| 00:02:02 |
| 5 | TABLE ACCESS FULL | N_VOICE | 968K| 38M| | 1753 (1)| 00:00:22 |
| 6 | TABLE ACCESS FULL | M_VOICE | 1417K| 52M| | 2479 (1)| 00:00:30 |
|* 7 | FILTER | | | | | | |
| 8 | TABLE ACCESS FULL | N_VOICE | 968K| 38M| | 1754 (1)| 00:00:22 |
|* 9 | TABLE ACCESS FULL | M_VOICE | 1 | 29 | | 2479 (1)| 00:00:30 |
Una forma simple de acelerar la consulta es crear un índice basado en funciones:
CREATE INDEX indexname1 ON N (timestamp+5/86400);
CREATE INDEX indexname2 ON N (timestamp+6/86400);