2013-10-17 14 views
5

Sto scrivendo una funzione in ColdFusion che restituisce il primo paio di record che corrispondono all'ingresso dell'utente, nonché il conteggio totale dei record corrispondenti nell'intero database. La funzione verrà utilizzata per alimentare un completamento automatico, quindi la velocità/efficienza sono le sue preoccupazioni principali. Ad esempio, se la funzione riceve input "bl", potrebbe tornare {sampleMatches:["blue", "blade", "blunt"], totalMatches:5000}trovare sottoinsieme di record in modo efficiente e conteggio totale

Ho tentato di fare questo in una singola query a fini di velocità, e finito con qualcosa che si presentava così:

select record, count(*) over() 
from table 
where criteria like :criteria 
and rownum <= :desiredCount 

Il problema con questa soluzione è che count(*) over() restituisce sempre il valore di :desiredCount. Ho visto una domanda simile alla mia here, ma la mia app non ha i permessi per creare una tabella temporanea. Quindi c'è un modo per risolvere il mio problema in una query? C'è un modo migliore per risolverlo? Grazie!

+0

i tuoi "criteri" saranno limitati a una serie di criteri per i quali sai che puoi utilizzare un indice? Se l'utente può impostare qualsiasi criterio pazzo, eseguirai un sacco di scansioni complete – tbone

+0

Per curiosità, se la funzione deve essere utilizzata per il completamento automatico, qual è lo scopo del conteggio? –

+0

@tbone la colonna criteri è già indicizzata – Josh

risposta

5

sto scrivendo questo in cima alla mia testa, così si dovrebbe assolutamente avere in tanto questo, ma credo che l'uso seguente CTE

  • richiede solo di scrivere le condizioni di una volta
  • solo i rendimenti la quantità di record specificato
  • ha il conteggio totale corretta aggiunto a ciascun record
  • e viene valutata solo una volta

SQL Statement

WITH q AS (
    SELECT record 
    FROM table 
    WHERE criteria like :criteria 
) 
SELECT q1.*, q2.* 
FROM q q1 
     CROSS JOIN (
     SELECT COUNT(*) FROM q 
     ) q2 
WHERE rownum <= :desiredCount 
+1

Questo l'ha fatto, grazie! Per farlo funzionare ho dovuto rimuovere le parole chiave 'as', ma si è svolto senza problemi altrimenti. – Josh

+0

@ Ben - hai rimosso la parola chiave 'as' perché non è supportata da oracle, tx, ma rimuovere gli alias non può essere corretto ?! * (Non posso testarlo adesso) * –

+0

No, scusa se ero stupido. Hai bisogno degli alias. – Ben

3

Una subquery nidificato deve restituire i risultati che si desidera

select record, cnt 
    from (select record, count(*) over() cnt 
      from table 
     where criteria like :criteria) 
where rownum <= :desiredCount 

Ciò, però, forzare Oracle per elaborare completamente la query in modo da generare il preciso count. Sembra improbabile che ciò sia ciò che si desidera se si sta tentando di eseguire un completamento automatico in particolare quando Oracle potrebbe decidere che sarebbe più efficiente eseguire una scansione tabella su table se :criteria è solo poiché tale predicato non è abbastanza selettivo. Sei davvero sicuro di aver bisogno di un conteggio accurato del numero di risultati? Sei sicuro che il tuo tavolo sia abbastanza piccolo/il tuo sistema sia abbastanza veloce/i tuoi predicati siano abbastanza selettivi da essere un requisito che potresti realisticamente incontrare? Sarebbe possibile restituire una stima meno costosa (ma meno accurata) del numero di righe? Oppure limitare lo count a qualcosa di più piccolo (ad esempio 100) e mostrare all'interfaccia utente qualcosa come "e oltre 100 risultati"?

+0

+1 per il suggerimento di stima "100+ .." – Leigh

+0

Per questo caso specifico ho bisogno del conteggio esatto. Ma per i bisogni futuri, come potrei fare per costruire un preventivo? – Josh

+2

@Josh - Dipende. È possibile generare un piano di query, ad esempio, e utilizzare il numero stimato di righe restituite. Puoi usare la clausola 'SAMPLE' e moltiplicare per un fattore appropriato. È possibile creare istogrammi basati sulla prevalenza dei dati e aggiornarli periodicamente (o persino utilizzare potenzialmente gli istogrammi generati dall'ottimizzatore). –

Problemi correlati