Newsgroup: it.comp.lang.visual-basic
Titolo: Velocità di INSERT INTO ... WHE RE NOT IN ...

Salve... ho un problema di velocità nell'utilizzo di INSERT INTO.
Qualche settimana fa postai una richiesta simile riguardo MySQL (MySQL 
ma quanto è lento/veloce?).
Ora però la situazione è leggermente diversa.
In pratica io leggo da un file sequenziale roba come 10.000 record alla 
volta, che accodo in una tabella temporanea (Temp).
I dati devono essere aggiunti alla tabella Telefonate che è di struttura 
IDENTICA a Temp.
Però per accertarmi di non duplicare le telefonate lette (e quindi 
calcolare costi sbagliati) controllo che il numerochiamante, la data e 
l'ora inizio telefonata non siano presenti già nella tabella chiamate.
Quindi faccio una query del tipo:
INSERT INTO Telefonate (Campo1, Campo2, ..., CanpoN) SELECT Campo1, 
Campo2, ..., CampoN FROM Temp WHERE NumeroChiamante & '|' & Data & '|' & 
'|' & InizioTelefonata NOT IN (SELECT NumChiamante & '|' & Data & '|' & 
InizioTelefonata FROM Telefonate)
In questo modo dovrei essere sicuro che le telefonate non si duplichino.
Però quando la tabella Telefonate è vuota, l'importazione è rapidissima 
(roba di secondi).
Quando tento di importare le stesse telefonate dallo stesso file (e 
quindi non dovrei aggiungere nulla perchè sono tutte doppioni), si 
popola la tabella Temp e la chiamata a INSERT INTO ... WHERE ... ecc. 
ecc. è lentissima. Sono passati 15 minuti da quando è partita la query 
di inserimento ma ancora nessun segno di vita dal pc.
Come posso velocizzare la cosa? Ho provato a indicizzare i campi che uso 
per il confronto, ma credo che unendoli con la '&' nella query 
significhi generare un nuovo campo temporaneo da usare per il confronto, 
e questo campo non è indicizzato quindi ci mette un sacco a controllare 
prima di aggiungere.
Come faccio?
-- 
Rivolterò il mondo per trovarlo, e anche se andasse in Indocina uno dei 
nostri starà nascosto in una ciotola di riso pronto a sparargli nel culo.
(Pulp Fiction)

 ha scritto nel messaggio
news:40b4...@x-privat.org...

Ciao,  prova con una bella Left Join, in genere se sostituita all'operatore
IN centuplica la velocità di esecuzione.
---------------------
INSERT INTO Telefonate (Campo1,Campo2,Campo3,Campo4)
SELECT P.Campo1,P.Campo2,P.Campo3,P.Campo4
FROM Tmp P Left Join Telefonate T
         ON P.NumeroChiamante =T.NumeroChiamante AND
                P.Data =T.Data AND
                P.InizioTelefonata =T.InizioTelefonata AND
WHERE   T.NumeroChiamante IS NULL
      AND  T.Data IS NULL
      AND  T.InizioTelefonata IS NULL
-------------------------
Ciao Giorgio

       AND  T.InizioTelefonata IS NULL
Non capisco una cosa: come mi giustifichi quella serie di ON... se poi 
devono essere Null nella clausola where?


 
E' una left join e quindi se non c'e' corrispondenza tra il record della 
tabella di sinistra e quella di destra, i campi di quella di destra 
vengono riempiti con NULL.
(esempio tabella clienti e tabella ordini volendo visualizzare gli 
ordini dei clienti, scriverai select clienti.nome, ordini.numero, 
ordini.data from clienti left join ordini on 
clienti.id
=ordini.idcliente. Se un cliente non ha ordini otterrai un 
record rossi - null - null).
ciao
	maxx
-- 
NOSPAM: Rimuovere i trattini dallo username!
Cut hyphens from my username!


non devo giustificarti un bel niente, è una semplice query di ricerca dati
non corrispondenti, faccio prima a farti un semplice esempio.
Tabella1: Campo1
---------
A
B
C
D
E
---------
Tabella2 Campo2
----------
A
E
----------
Query con left Join Tra le due tabelle
-------------------------
SELECT Campo1,Campo2
FROM Tabella1 Left Join Tabella2
     ON Tabella1.Campo1=Tabella2.Campo2
-------------------------
Risultato
Campo1 Campo2
---------------------
A              A
B              NULL
C              NULL
D              NULL
E               E
--------------------
Query di ricerca dati non corrispondenti
-----------------------------
SELECT Campo1,Campo2
FROM Tabella1 Left Join Tabella2
     ON Tabella1.Campo1=Tabella2.Campo2
WHERE Campo2 IS NULL
-------------------------
Risultato
Campo1 Campo2
---------------------
B              NULL
C              NULL
D              NULL
--------------------
Ciao Giorgio

Si grazie ad entrambi per la spiegazione :)
Il fatto è che capisco certe query soltanto immaginando passo passo cosa 
succede alla richiesta:
SELECT Campo1,Campo2
FROM Tabella1 Left Join Tabella2
      ON Tabella1.Campo1=Tabella2.Campo2
WHERE Campo2 IS NULL
l'ho capitoa facendo prima a mente il LEFT JOIN e quindi ottenendo la 
tabella finale riempita con i NULL dove non c'è corrispondenza, e poi 
filtrando il tutto con la WHERE... e così m'è apparsa la visione della 
tabella finale che poi ho visto nel post così come l'ho immaginata :D
Grazie!!!!
Ora in effetti faccio quell'accodamento in un secondo netto rispetto ai 
15 minuti di prima (e chissà quanti altri se non avessi bloccato il 
programma).
