Un modo più efficiente di impaginare i risultati della ricerca

0

Sto creando un sito Web in PHP in cui l'utente può cercare un grande database MySQL. All'utente viene mostrato il primo risultato. Voglio il pulsante next per portare l'utente al risultato successivo e così via.

La soluzione banale è che ogni pagina dei risultati esegua la query di ricerca dell'utente di nuovo e usi OFFSET e LIMIT per ottenere il risultato n che viene visualizzato. Ma questo sembra un algoritmo di Schlemiel the Painter : rieseguire la stessa query più e più volte per ottenere il < em> n -th risultato è inefficiente.

Dal momento che gli altri devono aver affrontato questa situazione prima: come è risolto questo problema?

    
posta Daniel Pelsmaeker 16.09.2013 - 23:21
fonte

2 risposte

1

Non è l'algoritmo di Shlemiel; ottenere la pagina 16 richiede praticamente esattamente il tempo di ottenere la pagina 1.

Sì, hai bisogno di una nuova query per pagina, ma ognuna di queste query ottiene solo un valore di una pagina di dati. Le alternative sono peggiori: se ottieni tutti dati in una volta sola e poi li filtri, avrai ancora bisogno di una query per richiesta, ma ora ognuna di queste query ottiene l'intera set di risultati, e farai il partizionamento in PHP - ma un DBMS è molto più efficace del tuo codice PHP scritto a mano. È possibile memorizzare l'intero processo, ma questo ha due aspetti negativi: si interroga ancora l'intero set di dati al primo caricamento, il che significa che qualsiasi richiesta su una cache obsoleta richiede più tempo del necessario e occorre implementare la memorizzazione nella cache, che potrebbe aggiungere un po 'di significato spese generali. Inoltre, proprio come nell'esempio annesso, è ancora necessario eseguire l'impaginazione in PHP.

Se dovesse risultare che la tua soluzione è troppo lenta, dovresti prima guardare lo schema del tuo database. Assicurati di avere gli indici appropriati nelle tabelle pertinenti. Denormalizza se devi. Se non lo fai, prendi in considerazione la memorizzazione nella cache di singole pagine.

Infine, se hai bisogno di funzionalità di ricerca scalabili, considera l'utilizzo di qualcosa che è specializzato nell'indicizzazione di documenti, ad es. Solr. Queste cose sono molto meglio per l'indicizzazione e la ricerca di documenti di quanto MySQL possa mai sperare di essere.

    
risposta data 17.09.2013 - 15:08
fonte
1

Quindi questa è fondamentalmente la cosa migliore che puoi fare secondo me. È molto più scalabile che mantenere l'intero set di risultati in memoria e riutilizzarlo tra le richieste di pagina. Ma ovviamente è difficile giudicare senza vedere prima i requisiti del tuo software.

Se hai bisogno di qualcosa di più sofisticato, a seconda del tuo caso d'uso puoi memorizzare i risultati della query a livello locale, o se i risultati cambiano raramente puoi persino pre-generare la pagina nel back-end (una query a determinati intervalli, gli utenti ottengono risultati statici). Questo è fondamentalmente ciò che CQRS è progettato per fornire:

link
link

Estratto: "CQRS tratta di un'architettura appropriata per le applicazioni collaborative multiutente. Prende in considerazione in modo esplicito fattori come la stoltezza dei dati e la volatilità e sfrutta tali caratteristiche per creare costrutti più semplici e scalabili.

Le architetture a livelli standard non si occupano esplicitamente di nessuno di questi problemi. Mentre mettere tutto nello stesso database può essere un passo nella direzione della gestione della collaborazione, la staleness è solitamente esacerbata in quelle architetture dall'uso di cache come ripensamento del miglioramento delle prestazioni. "

    
risposta data 16.09.2013 - 23:36
fonte

Leggi altre domande sui tag