C’è una differenza tra Seleziona * e Seleziona

Sto usando MS SQL Server 2005. C’è una differenza, tra il motore SQL, tra

SELECT * FROM MyTable; 

e

 SELECT ColA, ColB, ColC FROM MyTable; 

Quando ColA, ColB e ColC rappresentano tutte le colonne del tavolo?

Se sono uguali, c’è una ragione per cui dovresti comunque usare la seconda? Ho un progetto che è pesante su LINQ e non sono sicuro che lo standard SELECT * che genera sia una ctriggers pratica, o se dovrei sempre essere un .Select () su di esso per specificare quali colonne voglio.

EDIT: modificato “Quando ColA, ColB e ColC sono tutte le colonne del tavolo?” a “Quando ColA, ColB e ColC rappresentano tutte le colonne del tavolo?” per chiarezza.

In generale, è meglio essere espliciti, quindi Select col1, col2 from Table è meglio. Il motivo è che a un certo punto è ansible aggiungere una colonna aggiuntiva a quella tabella e causare il ritorno di dati non necessari dalla query.

Questa non è una regola dura e veloce.

1) Il secondo è più esplicito su quali colonne vengono restituite. Il valore del 2 ° quindi è quanto valuti esplicitamente sapere quali colonne ritornano.

2) Questo implica potenzialmente meno dati restituiti quando ci sono più colonne di quelle esplicitamente utilizzate.

3) Se si modifica la tabella aggiungendo una nuova colonna, la prima query cambia e la seconda no. Se hai codice come “per tutte le colonne restituite fai …”, i risultati cambiano se usi il primo, ma non il secondo.

Farò arrabbiare un sacco di gente con me, ma soprattutto se aggiungo colonne più tardi, solitamente mi piace usare la tabella SELECT * FROM. Sono stato chiamato pigro per questo motivo, perché se apportassi qualche modifica ai miei tavoli, mi piacerebbe non rintracciare tutti i proc memorizzati che usano quella tabella, e cambiarla semplicemente nelle classi del livello di accesso ai dati nella mia applicazione . Ci sono casi in cui specificherò le colonne, ma nel caso in cui sto cercando di ottenere un “object” completo dal database, preferirei semplicemente usare “*”. E, sì, so che la gente mi odierà per questo, ma mi ha permesso di essere più veloce e privo di bug mentre aggiungevo campi alle mie applicazioni.

I due lati del problema sono i seguenti: Le specifiche esplicite delle colonne offrono prestazioni migliori man mano che vengono aggiunte nuove colonne, ma * le specifiche non richiedono manutenzione man mano che vengono aggiunte nuove colonne.

Quale usare dipende dal tipo di colonne che ci si aspetta di aggiungere alla tabella e qual è il punto della query.

Se si sta utilizzando la tabella come backing store per un object (che sembra probabile nel caso LINQ-to-SQL), probabilmente si desidera aggiungere eventuali nuove colonne a questa tabella nell’object e viceversa. Li stai mantenendo in parallelo. Per questo motivo, in questo caso, * le specifiche nella clausola SELECT sono corrette. Le specifiche esplicite ti darebbero un po ‘di manutenzione ogni volta che qualcosa è cambiato, e un bug se non hai aggiornato l’elenco dei campi correttamente.

Se la query restituirà molti record, è probabile che tu stia meglio con specifiche esplicite per motivi di prestazioni.

Se entrambe le cose sono vere, prendi in considerazione due domande diverse.

È necessario specificare un elenco di colonne esplicito. SELECT * riporterà più colonne del necessario per creare più IO e traffico di rete, ma soprattutto potrebbe richiedere ricerche aggiuntive anche se esiste un indice di copertura non in cluster (su SQL Server).

Alcuni motivi per non usare la prima affermazione (selezionare *) sono:

  1. Se si aggiungono alcuni campi di grandi dimensioni (una colonna BLOB sarebbe pessima) in seguito a quella tabella, si potrebbero riscontrare problemi di prestazioni nell’applicazione
  2. Se la query era una query JOIN con due o più tabelle, alcuni dei campi potrebbero avere lo stesso nome . Sarebbe meglio assicurare che i nomi dei tuoi campi siano diversi.
  3. Lo scopo della query è più chiaro con la seconda affermazione da un punto di vista estetico di programmazione

Quando si seleziona ciascun campo singolarmente, è più chiaro quali campi vengono effettivamente selezionati.

SELECT * è una ctriggers pratica nella maggior parte dei posti.

  • Cosa succede se qualcuno aggiunge una colonna BLOB da 2 GB a quella tabella?
  • Qual è qualcuno aggiunge davvero una colonna a quel tavolo?

È un bug che aspetta di succedere.

Un paio di cose:

  • Un buon numero di persone ha pubblicato qui raccomandando contro l’uso di *, e ha dato molte buone ragioni per quelle risposte. Su altre 10 risposte finora solo una non raccomanda l’elenco delle colonne.
  • Le persone spesso fanno eccezioni a questa regola quando pubblicano messaggi per aiutare siti come StackOverflow, perché spesso non sanno quali colonne sono nella tua tabella o sono importanti per la tua query. Per questo motivo, vedrai un sacco di codice qui e altrove sul web che utilizza la syntax *, anche se il poster tenderà ad evitarlo nel suo codice.

È buono per la compatibilità diretta.

Quando usi

 SELECT * FROM myTable 

e in “myTable” ci sono 3 colonne. Ottieni gli stessi risultati di

 SELECT Column1, Column2, Column3 FROM myTable 

Ma se aggiungi una nuova colonna in futuro, otterrai risultati diversi.

Ovviamente, se si modifica il nome di una colonna esistente, nel primo caso si ottengono risultati e nel secondo caso si verifica un errore (penso che si tratti di un comportamento corretto dell’applicazione).

Se il tuo codice si basa su determinate colonne in un determinato ordine, devi elencare le colonne. In caso contrario, non fa davvero la differenza se si utilizza “*” o si scrivono i nomi delle colonne nell’istruzione select.

Un esempio è se inserisci una colonna in una tabella.

Prendi questo tavolo: ColA ColB ColC

Potresti avere una query:

 SELECT * FROM myTable 

Quindi il codice potrebbe essere:

 rs = executeSql("SELECT * FROM myTable") while (rs.read()) Print "Col A" + rs[0] Print "Col B" + rs[1] Print "Col C" + rs[2] 

Se aggiungi una colonna tra ColB e ColC, la query non restituirà ciò che stai cercando.

Per LinqToSql, se si prevede di modificare tali record in un secondo momento, è necessario recuperare l’intero record in memoria.

Dipende da cosa intendi per “differenza”. Esiste l’ovvia differenza di syntax, ma la vera differenza è una delle prestazioni.

Quando dici SELECT * FROM MyTable , stai dicendo al motore di query SQL di restituire un set di dati con tutte le colonne da quella tabella, mentre SELECT ColA, ColB, ColC FROM MyTable indica al motore di query di restituire un set di dati con solo ColA , ColB e ColC dal tavolo.

Supponi di avere una tabella con 100 colonne definite come CHAR [10]. SELECT * restituirà 100 colonne * 10 byte di dati SELECT ColA, ColB, ColC mentre SELECT ColA, ColB, ColC restituiranno 3 colonne * 10 byte di dati. Questa è una differenza enorme nella quantità di dati che vengono passati indietro attraverso il filo.

Specificando l’elenco delle colonne è anche più chiaro di quali colonne sei interessato. Lo svantaggio è che se aggiungi / rimuovi una colonna dalla tabella devi assicurarti che l’elenco delle colonne sia aggiornato, ma penso che sia un piccolo prezzo rispetto al guadagno in termini di prestazioni.

 SELECT * FROM MyTable 

selezionare * dipende dall’ordine delle colonne nello schema, quindi se si fa riferimento al risultato impostato dal numero di indice della raccolta si guarderà alla colonna sbagliata.

 SELECT Col1,Col2,Col3 FROM MyTable 

questa query ti darà una collezione che rimarrà invariata nel tempo, ma quanto spesso cambi l’ordine delle colonne?

Una rapida occhiata al piano di esecuzione della query mostra che le query sono le stesse.

La regola generale è che si desidera limitare le query solo ai campi che è necessario restituire.

selezionare ogni colonna è meglio di solo * perché se si aggiunge o si elimina una nuova riga, si deve guardare il codice e dare un’occhiata a ciò che si stava facendo con i dati recuperati.
Inoltre, ti aiuta a capire meglio il tuo codice e ti permette di usare alias come nomi di colonne (nel caso tu stia eseguendo un join di tabelle con una colonna che condivide il nome)

Un esempio del perché mai (imho) dovrebbe usare SELECT *. Questo non riguarda MSSQL, ma piuttosto MySQL. Le versioni precedenti alla 5.0.12 hanno restituito colonne da determinati tipi di join in modo non standard. Ovviamente, se le tue query definiscono quali colonne vuoi e in quale ordine non hai problemi. Immagina il divertimento se non lo fanno.

(Una ansible eccezione: la tua query SELEZIONA da una sola tabella e identifica le colonne nel tuo linguaggio di programmazione prescelto per nome anziché per posizione.)

L’utilizzo di “SELECT *” ottimizza per la digitazione del programmatore. Questo è tutto. Questo è l’unico vantaggio.