Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2007
    Messaggi
    18

    Limitare la ricerca in una query MySQL

    Salve a tutti, ho una domanda per ottimizzare il tempo necessario per effettuare alcune query.
    E' possibile limitare la ricerca ad un dato numero di record estratti?
    Mi spiego meglio: voglio dire al database, trova i primi 10 record che soddisfano determinati criteri, e quando li hai trovati, interrompi la ricerca.
    Ci sarebbe la clausola LIMIT, ma questa agisce solo sulla visualizzazione dei record trovati, in sostanza limita solo il numero di record che vengono visualizzati, ma la query è portata a termine fino in fondo.
    Esiste invece una qualche procedura per interrrompere la ricerca una volta trovato il num. di record specificato, in modo da rendere la query più veloce? Magari con un WHERE? boh

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2007
    Messaggi
    595
    Attenzione
    Se la query e gli indici sono strutturati bene, LIMIT funziona benissimo e si interrompe al momento giusto
    Certo è che se tu fai un query ordinando per un campo "non indicizzato" allora mysql è obbligato a guardarsi tutta la tabella, estrarsi tutti i dati, ordinarli e solo allora può decidere quali sono "i primi dieci"
    Se invece l'ordinamento/group by/condizioni where sono strutturate ottimizzando al meglio gli indici, LIMIT è perfetto ed è LA soluzione

    Immaginiamo questa situazione

    SELECT * FROM tabella ORDER BY campo LIMIT 10

    Se "campo" non è un indice di "tabella" allora mysql è costretto ad analizzare TUTTA la tabella prima di dirti quali sono i "primi 10" e non c'è altro modo al mondo per risolvere il problema
    Se invece "campo" è dichiarato quantomeno come "index" allora mysql potrà tranquillamente analizzare direttamente i primi 10

    L'argomento non si esaurisce ovviamente qui, ma coinvolge le condizioni di WHERE, di JOIN, di GROUP BY e molte altre variabili. Ma la soluzione è solo ed unicamente quella, strutturare bene tabelle e applicazione, tenendo presente la creazione di indici combinati, adatti a rendere migliori le query più "comuni" e "frequenti" dell'applicazione stessa

  3. #3
    Scusa Leilond se intervengo, ma non è proprio esattamente così.
    Mi spiego meglio con un esempio:

    SELECT *
    FROM tabella1, tabella2
    WHERE (tabella1.campo='Prova')
    LIMIT 10

    Innanzitutto viene effettuato il "prodtto cartesiano" tra le 2 tabelle, ossia si prendono tutte le combinazioni delle righe della tabella1 * le righe della tabella2. Supponendo che tabella1 ha 4 record e tabella2 ne ha 5 allora il risultato sarà di 20 record.
    Poi a queste righe si applica la clausola WHERE con la quale si considerano solo certe righe e non tutte. Supponiamo che delle 20 righe ne rimangano 13. Infine con LIMIT se ne prendono solo 10 le quali costituiranno il cosiddetto Result Set.

    L'indicizzazione risulta offrire dei miglioramenti significativi, quando le ricerche nella tabella riguardano proprio il campo indicizzato.
    Nell'esempio che hai fatto:

    SELECT * FROM tabella ORDER BY campo LIMIT 10

    prima si prendono tutti i record della tabella, poi questi vengono ordinati su "campo" (e questa è un'operazione abbastanza gravosa) e poi, di questi se ne prendono 10.
    Se la tabella risulta essere indicizzata su campo, allora l'operazione di ordinamento non prenderà risorse (o comunque molto minimali) per cui la query risulta essere più efficiente.


    Rispondendo a trhacker, sinceramente non so se sia possibile ciò che hai chiesto.

    Ciao.

  4. #4
    Avevo scritto:

    Nell'esempio che hai fatto:

    SELECT * FROM tabella ORDER BY campo LIMIT 10

    prima si prendono tutti i record della tabella, poi questi vengono ordinati su "campo" (e questa è un'operazione abbastanza gravosa) e poi, di questi se ne prendono 10.

    Scusate ma non ricordo molto bene, può darsi che prima ne prende 10 e poi li ordina.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2007
    Messaggi
    595
    Originariamente inviato da gianf_tarantino
    Scusa Leilond se intervengo, ma non è proprio esattamente così.
    Mi spiego meglio con un esempio:

    SELECT *
    FROM tabella1, tabella2
    WHERE (tabella1.campo='Prova')
    LIMIT 10

    Innanzitutto viene effettuato il "prodtto cartesiano" tra le 2 tabelle, ossia si prendono tutte le combinazioni delle righe della tabella1 * le righe della tabella2. Supponendo che tabella1 ha 4 record e tabella2 ne ha 5 allora il risultato sarà di 20 record.
    Poi a queste righe si applica la clausola WHERE con la quale si considerano solo certe righe e non tutte. Supponiamo che delle 20 righe ne rimangano 13. Infine con LIMIT se ne prendono solo 10 le quali costituiranno il cosiddetto Result Set.
    Questo NON contraddice quello che ho detto prima io. Ho detto appunto che se la query non ha selezioni efficenti a livello di indici, non c'è modo di usare limit per giovarne
    La tua query è sicuramente NON ottimizzabile, poichè non c'è nessun elemento di join che permetta di utilizzare un ordinamento prima dell'estrazione, la qual cosa mi OBBLIGA a prendere tutti gli elementi e poi selezionarne 10
    In un esempio che posso fare io, simile al tuo
    SELECT * FROM tabella1,tabella2
    WHERE tabella1.campo="prova" and tabella2.id = tabella1.id_tabella2
    LIMIT 10

    Se campo è indice e tabella1 e id è primary key di tabella2, la select scorrerà i record NATURALMENTE fermandosi al decimo elemento utile, poichè non ha alcun bisogno di fare il "prodotto cartesiano" prima dell'esecuzione, ma ha accesso diretto tramite le chiavi

    L'indicizzazione risulta offrire dei miglioramenti significativi, quando le ricerche nella tabella riguardano proprio il campo indicizzato.
    Nell'esempio che hai fatto:

    SELECT * FROM tabella ORDER BY campo LIMIT 10

    prima si prendono tutti i record della tabella, poi questi vengono ordinati su "campo" (e questa è un'operazione abbastanza gravosa) e poi, di questi se ne prendono 10.
    Se la tabella risulta essere indicizzata su campo, allora l'operazione di ordinamento non prenderà risorse (o comunque molto minimali) per cui la query risulta essere più efficiente.
    Qui sono io a contraddire
    Se "campo" è indice di tabella, l'estrazione avviene solo per 10 elementi, NON prende tutto e poi ordina

    Esiste una fantastica funzione in MYSQL che si chiama EXPLAIN. Ogni volta che si usa un query è buona norma (quando possibile) stamparla, ed usare EXPLAIN per verificare il corretto uso degli indici. Questa funzione (va un po' studiata _QUI_ ) ma se la si usa per bene può dare un vero sprint a qualsiasi applicazione che fa largo uso di sql

    P.S.
    Consiglio anche questa lettura
    http://dev.mysql.com/doc/refman/5.0/...imization.html

  6. #6
    A riscusami Leilond, probabilmente non ho io ben capito l'uso degli indici.
    Cmq. grazie per la delucidazione.
    Ciao.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2007
    Messaggi
    18
    Grazie ragazzi, spiegazione molto utile

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.