Domanda

Sto scrivendo un programma che invia un'e-mail all'ora locale specifica di un cliente.Ho un metodo .NET che accetta un fuso orario, un'ora e un fuso orario di destinazione e restituisce l'ora in quel fuso orario.Quindi il mio metodo è selezionare ogni fuso orario distinto nel database, controllare se è l'ora corretta utilizzando il metodo, quindi selezionare tutti i client dal database con quel fuso orario.

La query sarà simile a una di queste.Tieni presente che l'ordine del set di risultati non ha importanza, quindi un'unione andrebbe bene.Quale funziona più velocemente o fanno davvero la stessa cosa?

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)

O

SELECT email FROM tClient WHERE timezoneID = 1
    UNION ALL SELECT email FROM tClient WHERE timezoneID = 4
    UNION ALL SELECT email FROM tCLIENT WHERE timezoneID = 9

Modificare: timezoneID è una chiave esterna per tTimezone, una tabella con chiave primaria timezoneID e campo varchar(20) timezoneName. Inoltre, sono andato con WHERE IN poiché non avevo voglia di aprire l'analizzatore.

Modifica 2: La query elabora 200.000 righe in meno di 100 ms, quindi a questo punto ho finito.

È stato utile?

Soluzione

EHI!Queste query non sono equivalenti.

I risultati saranno gli stessi solo se si presuppone che un'e-mail appartenga solo a un fuso orario.Ovviamente lo fa, tuttavia il motore SQL non lo sa e cerca di rimuovere le doppiezze.Quindi la prima query dovrebbe essere più veloce.

Usa sempre UNION ALL, a meno che tu non sappia perché vuoi usare UNION.

Se non sei sicuro di quale sia la differenza, guarda Questo Quindi domanda.

Nota:a cui appartiene quell'urlo versione precedente di domanda.

Altri suggerimenti

Per la maggior parte delle domande sulle prestazioni relative al database, la vera risposta è eseguirlo e analizzare cosa fa il DB per il tuo set di dati.Esegui un piano o una traccia esplicativi per verificare se la tua query raggiunge gli indici corretti o crea indici, se necessario.

Probabilmente opterei per il primo utilizzando la clausola IN poiché porta la maggior parte della semantica di ciò che desideri.Il timezoneID sembra una chiave primaria su alcune tabelle del fuso orario, quindi dovrebbe essere una chiave esterna sull'e-mail e indicizzata.A seconda dell'ottimizzatore DB, penserei che dovrebbe eseguire una scansione dell'indice sull'indice della chiave esterna.

La mia prima ipotesi sarebbe questa

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)
sarà più veloce in quanto richiede una sola scansione della tabella per trovare i risultati, ma suggerisco di controllare il piano di esecuzione per entrambe le query.

Non ho MS SQL Query Analyser a portata di mano per verificare effettivamente la mia ipotesi, ma penso che la variante WHERE IN sarebbe più veloce perché con UNION server dovrà eseguire 3 scansioni di tabelle mentre con WHERE IN ne servirà solo una.Se disponi di Query Analyser, controlla i piani di esecuzione per entrambe le query.

Su Internet potresti spesso incontrare suggerimenti per evitare di utilizzare WHERE IN, ma ciò si riferisce ai casi in cui vengono utilizzate le subquery.Quindi questo caso non rientra nell'ambito di questa raccomandazione e inoltre è più facile da leggere e comprendere.

Penso che nella domanda manchino diverse informazioni molto importanti.Prima di tutto, è di grande importanza che il timezoneID sia indicizzato o meno, se fa parte della chiave primaria, ecc.Consiglierei a tutti di dare un'occhiata all'analizzatore, ma secondo la mia esperienza la clausola WHERE dovrebbe essere più veloce, soprattutto con un indice.La logica è qualcosa del tipo: c'è un sovraccarico aggiuntivo nella query di unione, nel controllo dei tipi, dei numeri di colonna in ciascuno, ecc.

Nel libro "SQL Performance Tuning", gli autori hanno scoperto che le query UNION erano più lente in tutti i 7 DBMS testati (SQL Server 2000, Sybase ASE 12.5, Oracle 9i, DB2, ecc.): http://books.google.com/books?id=3H9CC54qYeEC&pg=PA32&vq=UNION&dq=sql+performance+tuning&source=gbs_search_s&sig=ACfU3U18uYZWYVHxr2I3uUj8kmPz9RpmiA#PPA33,M1

Il successivo DBMS potrebbe aver ottimizzato questa differenza, ma è dubbio.Inoltre, il metodo UNION è molto più lungo e difficile da mantenere (e se ne volessi un terzo?) rispetto al metodo UNION.l'IN.

A meno che tu non abbia una buona ragione per utilizzare UNION, attieniti al metodo OR/IN.

Alcuni Query Optimizer di DBMS modificano la tua query per renderla più efficiente, quindi a seconda del DBMS che utilizzi, probabilmente non dovresti preoccuparti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top