Mysql
 sql >> Database >  >> RDS >> Mysql

Inizia a visualizzare i risultati della query prima della fine della query

Parafrasando:

Sembra che quello che vorresti sia una sorta di sistema in cui possono esserci due (o più) thread al lavoro. Un thread sarebbe impegnato a recuperare in modo sincrono i dati dal database ea segnalarne l'avanzamento al resto del programma. L'altro thread si occuperebbe del display.

Non è chiaro che la tua query restituirà 500.000 righe (anzi, speriamo che non lo faccia), anche se potrebbe dover scansionare tutte le 500.000 righe (e potrebbe aver trovato solo 23 righe che corrispondono finora). Determinare il numero di righe da restituire è difficile; determinare il numero di righe da scansionare è più semplice; determinare il numero di righe già scansionate è molto difficile.

Pertanto, l'utente è passato oltre la 23a riga, ma la query non è stata ancora completata.

Ci sono un paio di problemi qui. Il DBMS (vero per la maggior parte dei database, e certamente per IDS) rimane vincolato fino alla connessione corrente sull'elaborazione dell'unica istruzione. È difficile ottenere un feedback sull'andamento di una query. È possibile esaminare le righe stimate restituite all'avvio della query (informazioni nella struttura SQLCA), ma è probabile che tali valori siano errati. Dovresti decidere cosa fare quando raggiungi la riga 200 di 23, oppure arrivi solo alla riga 23 di 5.697. È meglio di niente, ma non è affidabile. Determinare fino a che punto è progredita una query è molto difficile. E alcune query richiedono un'effettiva operazione di ordinamento, il che significa che è molto difficile prevedere quanto tempo ci vorrà perché non sono disponibili dati fino a quando non viene eseguito l'ordinamento (e una volta eseguito l'ordinamento, c'è solo il tempo necessario per comunicare tra il DBMS e l'applicazione per sospendere la consegna dei dati).

Informix 4GL ha molte virtù, ma il supporto per i thread non è uno di questi. Il linguaggio non è stato progettato pensando alla sicurezza dei thread e non esiste un modo semplice per adattarlo al prodotto.

Penso che quello che stai cercando sarebbe più facilmente supportato da due thread. In un programma a thread singolo come un programma I4GL, non c'è un modo semplice per andare a recuperare le righe mentre si attende che l'utente digiti un altro input (come 'scorri la pagina successiva piena di dati').

L'ottimizzazione FIRST ROWS è un suggerimento per il DBMS; può o non può dare un beneficio significativo alla performance percepita. Nel complesso, in genere significa che la query viene elaborata in modo meno ottimale dal punto di vista del DBMS, ma ottenere rapidamente risultati per l'utente può essere più importante del carico di lavoro sul DBMS.

Da qualche parte in basso in una risposta molto votata al ribasso, Frank ha gridato (ma per favore non gridare):

OK. La difficoltà qui è organizzare l'IPC tra i due processi lato client. Se entrambi sono collegati al DBMS, hanno connessioni separate e quindi le tabelle temporanee e i cursori di una sessione non sono disponibili per l'altra.

Non tutte le query generano una tabella temporanea, sebbene il set di risultati per un cursore di scorrimento di solito abbia qualcosa di approssimativamente equivalente a una tabella temporanea. IDS non ha bisogno di posizionare un blocco sulla tabella temporanea che supporta un cursore di scorrimento perché solo IDS può accedere alla tabella. Se fosse una normale tabella temporanea, non sarebbe comunque necessario bloccarla perché non è possibile accedervi se non dalla sessione che l'ha creata.

Forse un messaggio di stato più accurato sarebbe:

Searching 500,000 rows...found 23 matching rows so far

Probabilmente; puoi anche ottenere un conteggio veloce e accurato con 'SELECT COUNT(*) FROM TheTable'; questo non esegue la scansione di nulla ma accede semplicemente ai dati di controllo, probabilmente effettivamente gli stessi dati della colonna nrows della tabella SMI sysmaster:sysactptnhdr.

Quindi, generare un nuovo processo non è chiaramente una ricetta per il successo; devi trasferire i risultati della query dal processo generato al processo originale. Come ho affermato, una soluzione multithread con display separati e thread di accesso al database funzionerebbe in un certo senso, ma ci sono problemi nel farlo usando I4GL perché non è thread-aware. Dovresti ancora decidere in che modo il codice lato client memorizzerà le informazioni per la visualizzazione.