Domanda

Quando utilizzo JDBC, mi imbatto spesso in costrutti come

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int id = rs.getInt(1);
    // Some other actions
}

Mi sono chiesto (e anche agli autori del codice) perché non usare le etichette per recuperare i valori delle colonne:

int id = rs.getInt("CUSTOMER_ID");

La migliore spiegazione che ho sentito è qualcosa che riguarda le prestazioni. Ma in realtà, rende l'elaborazione estremamente veloce? Non ci credo, anche se non ho mai eseguito misurazioni. Anche se il recupero per etichetta sarebbe un po 'più lento, tuttavia, a mio avviso offre una migliore leggibilità e flessibilità.
Qualcuno potrebbe darmi una buona spiegazione di come evitare di recuperare i valori di colonna dall'indice di colonna anziché dall'etichetta della colonna? Quali sono i pro e i contro di entrambi gli approcci (forse relativi a determinati DBMS)?

È stato utile?

Soluzione

Dovresti usare etichette di stringa per impostazione predefinita.

Pro:

  • Indipendenza dell'ordine delle colonne
  • Migliore leggibilità / manutenibilità

Contro:

  • Non hai alcun controllo sui nomi delle colonne (accesso tramite stored procedure)

Quale preferiresti?

int?

  

int i = 1;
   customerId = resultSet.getInt (i ++);
   customerName = resultSet.getString (i ++);
   customerAddress = resultSet.getString (i ++);

o Stringhe?

  

customerId = resultSet.getInt (" customer_id ");
   customerName = resultSet.getString (" customer_name ");
   customerAddress = resultSet.getString (" customer_address ");

E se ci fosse una nuova colonna inserita nella posizione 1? Quale codice preferiresti? O se l'ordine delle colonne viene modificato, quale versione di codice dovresti cambiare?

Ecco perché dovresti usare etichette di stringa di default.

Altri suggerimenti

Avvertenza: qui diventerò bomba, perché questo mi fa impazzire.

Il 99% * delle volte, è una ridicola micro-ottimizzazione che le persone abbiano una vaga idea che rende le cose "migliori". Questo ignora completamente il fatto che, a meno che tu non sia in un ciclo estremamente stretto e impegnato su milioni di risultati SQL tutto il tempo , che si spera sia raro, non lo noterai mai. Per tutti coloro che non lo fanno, il costo in termini di tempo dello sviluppatore per mantenere, aggiornare e correggere i bug nell'indicizzazione delle colonne è di gran lunga maggiore del costo incrementale dell'hardware per la tua applicazione infinitamente meno performante.

Non codificare ottimizzazioni come questa in. Codice per la persona che la mantiene. Quindi osservare, misurare, analizzare e ottimizzare. Osserva di nuovo, misura di nuovo, analizza di nuovo e ottimizza di nuovo.

L'ottimizzazione è praticamente l'ultimo passo dello sviluppo, non il primo.

* La figura è composta.

La risposta è stata accettata, tuttavia, ecco alcune informazioni aggiuntive ed esperienza personale che non ho ancora visto avanzate.

Usa i nomi delle colonne (le costanti e non i letterali sono preferiti) in generale e se possibile. Ciò è più chiaro, è più facile da mantenere e le modifiche future hanno meno probabilità di violare il codice.

Vi è, tuttavia, un uso per gli indici di colonna. In alcuni casi questi sono più veloci, ma non sufficientemente da escludere i motivi sopra indicati per i nomi *. Questi sono molto utili quando si sviluppano strumenti e metodi generali relativi ai ResultSet . Infine, potrebbe essere necessario un indice perché la colonna non ha un nome (come un aggregato senza nome) o ci sono nomi duplicati, quindi non esiste un modo semplice per fare riferimento a entrambi.

* Nota che ho scritto alcuni driver JDBC e ho guardato all'interno di alcuni open source e internamente questi usano indici di colonna per fare riferimento alle colonne dei risultati. In tutti i casi con cui ho lavorato, il driver interno prima mappa un nome di colonna su un indice. Quindi, puoi facilmente vedere che il nome della colonna, in tutti quei casi, richiederebbe sempre più tempo. Questo potrebbe non essere vero per tutti i driver.

Dalla documentazione di Java:

  

L'interfaccia ResultSet fornisce metodi getter (getBoolean, getLong e così via) per recuperare i valori di colonna dalla riga corrente. I valori possono essere recuperati utilizzando il numero indice della colonna o il nome della colonna. In generale, l'utilizzo dell'indice di colonna sarà più efficiente. Le colonne sono numerate da 1. Per la massima portabilità, le colonne del set di risultati all'interno di ogni riga devono essere lette nell'ordine da sinistra a destra e ogni colonna deve essere letta una sola volta.

Naturalmente ogni metodo (nominato o indicizzato) ha il suo posto. Sono d'accordo che le colonne con nome dovrebbero essere quelle predefinite. Tuttavia, nei casi in cui è richiesto un numero enorme di loop e in cui l'istruzione SELECT è definita e mantenuta nella stessa sezione di codice (o classe), gli indici dovrebbero essere a posto - è consigliabile elencare le colonne selezionate, non solo " SELECT * FROM ... " ;, poiché qualsiasi modifica della tabella interromperà il codice.

Certo, l'uso dei nomi delle colonne aumenta la leggibilità e semplifica la manutenzione. Ma usare i nomi di colonna ha un rovescio. Come sai, SQL consente più nomi di colonna con lo stesso nome, non esiste alcuna garanzia che il nome della colonna digitato nel metodo getter di resultSet indichi effettivamente il nome della colonna a cui intendi accedere. In teoria, si preferisce usare numeri di indice anziché nomi di colonne, ma riduce la leggibilità ...

Grazie

Non credo che l'uso delle etichette influisca molto sulle prestazioni. Ma c'è un altro motivo per non usare String . O int s, per quella materia.

Valuta l'utilizzo delle costanti. L'uso di una costante int rende il codice più leggibile, ma ha anche meno probabilità di avere errori.

Oltre ad essere più leggibile, la costante ti impedisce anche di fare errori di battitura nei nomi delle etichette - il compilatore genererà un errore se lo fai. E qualsiasi IDE che valga qualcosa lo prenderà. Questo non è il caso se si utilizza String s ints .

Ho fatto un po 'di profiling delle prestazioni su questo argomento esatto su un database Oracle. Nel nostro codice abbiamo un ResultSet con numerose colonne e un numero enorme di righe. Dei 20 secondi (!) La richiesta richiede l'esecuzione del metodo oracle.jdbc.driver.ScrollableResultSet.findColumn (nome stringa) richiede circa 4 secondi.

Ovviamente c'è qualcosa che non va nel design generale, ma l'uso di indici anziché i nomi delle colonne probabilmente richiederebbe questi 4 secondi.

Puoi avere il meglio di entrambi! La velocità di utilizzo degli indici con la manutenibilità e la sicurezza dell'utilizzo dei nomi di colonna.

Prima di tutto, a meno che non si esegua il looping attraverso un set di risultati, utilizzare solo i nomi di colonna.

  1. Definisce un insieme di variabili intere, una per ogni colonna a cui accederai. I nomi delle variabili possono includere il nome della colonna: ad es. iLast_Name.

  2. Prima del ciclo del set di risultati, scorrere i metadati della colonna e impostare il valore di ciascuna variabile intera sull'indice di colonna del nome della colonna corrispondente. Se l'indice della colonna "Last_Name" è 3, imposta il valore di "iLast_Name" su 3.

  3. Nel ciclo del set di risultati utilizzare i nomi delle variabili intere nei metodi GET / SET. Il nome della variabile è un indizio visivo per lo sviluppatore / manutentore in merito al nome effettivo della colonna a cui si accede, ma il valore è l'indice della colonna e fornirà le migliori prestazioni.

NOTA: la mappatura iniziale (ovvero il nome della colonna nella mappatura dell'indice) viene eseguita una sola volta prima del ciclo anziché per ogni record e colonna nel ciclo.

Il driver JDBC si occupa della colonna per indicizzare la ricerca. Pertanto, se si estraggono i valori in base al nome della colonna ogni volta che il driver effettua una ricerca (in genere nella mappa hash) per verificare l'indice corrispondente per il nome della colonna.

Concordo con le risposte precedenti sul fatto che le prestazioni non sono qualcosa che può costringerci a selezionare nessuno degli approcci. Sarebbe opportuno considerare invece le seguenti cose:

  • Leggibilità del codice: per ogni sviluppatore che legge le etichette del tuo codice ha molto più senso degli indici.
  • Manutenzione: pensa alla query SQL e al modo in cui viene gestita. Cosa è più probabile che accada nel tuo caso dopo aver corretto / migliorato / refactoring la query SQL: cambiare l'ordine delle colonne estratte o cambiare i nomi delle colonne dei risultati. Mi sembra che cambiare l'ordine delle colonne estratte (come i risultati dell'aggiunta / eliminazione di nuove colonne nel set di risultati) abbia maggiori probabilità di accadere.
  • Incapsulamento: nonostante il modo in cui si sceglie, provare a isolare il codice in cui si esegue la query SQL e analizzare il set di risultati nello stesso componente e rendere solo questo componente consapevole dei nomi delle colonne e del loro mapping agli indici (se si è deciso per usarli).

L'uso dell'indice è un tentativo di ottimizzazione.

Il tempo risparmiato da questo è sprecato dallo sforzo supplementare necessario allo sviluppatore per cercare i dati necessari per verificare se il loro codice funzionerà correttamente dopo le modifiche.

Penso che sia il nostro istinto incorporato usare numeri anziché testo.

Oltre a cercare le etichette in Mappa, porta anche a una creazione di stringhe aggiuntiva. Anche se accadrà in pila ma comporta comunque un costo.

Tutto dipende dalla scelta individuale e fino ad oggi ho usato solo indici :-)

Come sottolineato da altri poster, mi atterrei ai nomi delle colonne a meno che tu non abbia un motivo davvero potente per non farlo. L'impatto sulle prestazioni è trascurabile rispetto, ad esempio, all'ottimizzazione delle query. In questo caso, la manutenzione è molto più importante di una piccola optmizzazione.

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