Domanda

Sono in esecuzione di query contro un 10g Oracle con JDBC (utilizzando i driver più recenti e le UCP come DataSource) al fine di recuperare CLOB (avg. 20k caratteri). Tuttavia le prestazioni sembra essere piuttosto male: il recupero lotto di 100 LOB prende 4s in media. L'operazione è anche nè di I / O né CPU né rete legata a giudicare dalle mie osservazioni.

La mia configurazione di prova si presenta così:

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");

dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");

final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);

j.query("SELECT bigClob FROM ...",

        new RowCallbackHandler() {

            public void processRow(final ResultSet rs) throws SQLException {

                String result = handler.getClobAsString(rs, "bigClob");

            }

        });

}

ho sperimentato con le dimensioni prelevare ma senza alcun risultato. Sto facendo qualcosa di sbagliato? Esiste un modo per accelerare il recupero CLOB quando si utilizza JDBC?

È stato utile?

Soluzione 4

Grazie per tutti i suggerimenti utili. Nonostante sia stato contrassegnato come risposta al problema la mia risposta è che non sembra esserci nessuna buona soluzione. Ho provato ad utilizzare formulazioni parallele, caratteristiche di conservazione differenti, temperatura preordinate. tavoli e altre cose. L'operazione sembra non essere legato ad alcuna caratteristica visibile attraverso le tracce o spiegare piani. Anche il parallelismo interrogazione sembra essere impreciso quando CLOB sono coinvolti.

Senza dubbio ci sarebbe opzioni migliori per affrontare con grandi CLOB (soprattutto di compressione) in un ambiente 11g, ma atm. Sono bloccato con 10 g.

ho optato ora per un andata e ritorno supplementare per il database in cui vi pre-elaborare i CLOB in una dimensione ottimizzata binari originari. Nelle distribuzioni precedenti questo è sempre stata una scelta molto veloce e sarà probabilmente vale la pena di mantenere una linea calcolata cache. La cache sarà invalidi aggiornamento utilizzando un processo persistente e AQ fino a quando qualcuno si presenta con un'idea migliore.

Altri suggerimenti

La mia passata esperienza di utilizzo di dati di tipo Oracle LOB per memorizzare grandi quantità di dati non è stata buona. E 'bene quando è sotto 4k in quanto memorizzare localmente come VARCHAR2. Una volta che è finita 4k, cominci a vedere degrado delle prestazioni. Forse, le cose possono essere migliorate dall'ultima volta che ho provato un paio di anni fa, ma qui ci sono le cose che ho trovato in passato per vostra informazione:

Per quanto i clienti hanno bisogno di ottenere LOB tramite server Oracle, si può considerare la seguente situazione interessante.

    Dati
  • pallonetto gareggeranno limitata SGA Cache con altro tipo di dati se oracolo decidere di memorizzare nella cache esso. Poiché i dati sono CLOB generale grande, quindi potrebbe spingere altri Dati
  • dati LOB vengono poveri disco leggere se Oracle non decidono di memorizzare nella cache, e streaming i dati al client.
  • frammentazione è probabilmente qualcosa che non hai ancora incontrato. Si vedrà se le applicazioni LOB eliminare, e Oracle cerca di riutilizzare il lob. Non so se il supporto Oracle in linea la deframmentazione del disco per lob (hanno per gli indici, ma ci vuole molto tempo in cui abbiamo provato precedente).

Hai menzionato 4s per 100 pallonetti di avg 20k, quindi è 40ms per pallonetti. Ricorda ogni lob ha bisogno di avere a recuperati tramite localizzatore Lob separato (non è nel risultato impostato di default). Questo è un viaggio di andata supplementare per ogni pallonetto, suppongo (non sono sicuro al 100% su questo dato che era qualche tempo fa) Se questo è il caso, suppongo che saranno almeno 5ms tempo in più per ogni viaggio di andata in ordine seriale , giusto? Se è così, le prestazioni è già primo limitata da lob sequenziale recupera. Si dovrebbe essere in grado di verificare questo monitoraggio il tempo trascorso in esecuzione SQL vs contenuti lob recupero. Oppure si può verificare questo escludendo la colonna pallonetto come suggerito dalla risposta precedente nel post, che dovrebbe dirvi se è pallonetto legato.

In bocca al lupo

  

La dimensione totale del set di risultati è nelle decine di migliaia - misurata nell'arco di tutto il recupero dei costi iniziali

C'è un ordine nella query? 10K righe è un bel po ', se deve essere ordinato.

Inoltre, il recupero del PK non è un test giusto rispetto recuperare l'intero CLOB. Oracle memorizza le righe della tabella con probabilmente molti in un blocco, ma ognuna delle CLOBs (se sono> 4K) verrà memorizzato fuori linea, ciascuna in una serie di blocchi. Scansione l'elenco dei PK è quindi sta per essere veloce. Inoltre, v'è probabilmente un indice sul PK, quindi Oracle può solo eseguire la scansione rapidamente i blocchi di indice e nemmeno accedere alla tabella.

4 secondi fa sembrare un po 'alto, ma è 2MB che deve essere possibile leggere dal disco e trasportato attraverso la rete al vostro programma Java. Network potrebbe essere un problema. Se si esegue una traccia di SQL della sessione esso si punta esattamente dove viene speso il tempo (letture del disco o di rete).

Ho avuto un problema simile e trovato il JDBC LOB di effettuare una chiamata di rete quando il accessin pallonetti.

A partire da Oracle 11.2g driver JDBC è possibile utilizzare un prefetch. Questo accelerato l'accesso di 10 volte ...

statement1.setFetchSize(1000);
if (statement1 instanceof OracleStatement) {
    ((OracleStatement) statement1).setLobPrefetchSize(250000);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top