Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: ottimizzare una query

  1. #1
    Utente di HTML.it L'avatar di Gabbro
    Registrato dal
    Nov 2000
    Messaggi
    828

    ottimizzare una query

    Salve sono su un server apache e db mysql.
    Ho una parte del sito dove gli utenti possono leggere i propri messaggi e la query è simile a questa:
    SELECT id, mittente, oggetto , data from messaggi where id_mittente = 18145 and fl<>2 ORDER BY id DESC limit 0, 10

    essendo il numero di regord grandissimo nell'ultimo periodo ho rilevato un enorme rallentamento quando viene fatta questa query. ho notato allora che se tolgo l' ORDER BY id DESC la query ci mette quasi un decimo del tempo che ci mette ora, però naturalmente non avrei gli ultimi messaggi arrivati visualizzati per primi ma i messaggi piu vecchi visualizzati per primi. allora ho pensato che potrei togliere l'order by id desc limit 0,10 e mettere tutti questi record in un array e visualizzarli al contrario secondo l'indice dell'array. secondo voi è una soluzione ottimale o posso trovare un metodo migliore per risolvere il problema?

  2. #2
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    A occhio e croce direi che peggioreresti le cose

    Il campo id_mittente non ha un indice?

  3. #3
    Se invece di visualizzare gli ultimi dieci e così via visualizzi i messaggi per settimane o giorni e quindi attraverso il WHERE filtri con un data<ora AND data>ieri mysql dovrà ordinare un numero drasticamente minore di record.

    Per come agisci tu adesso mysql fa questi passaggi (almeno per quanto ne so).

    -prende TUTTI i record che corrispondono col WHERE (e sono tutti i messaggi dell'utente dall'alba dei tempi)
    -li ordina (TUTTI)
    -prende i primi 10

    Se tu agisci per data invece succede questo
    -prende i messaggi mandati entro un determinato periodo
    -ordina SOLO quelli
    -se vuoi puoi prendere i primi 10 nel caso ce ne fossero di più nel periodo trattato

    Lungo le due rive del fiume gelato si stendeva la cupa e tetra foresta di abeti, dai quali il vento aveva appena spazzato il manto di brina. Nella luce crepuscolare quegli abeti neri e sinistri sembravano inclinarsi l'uno verso l'altro. Un silenzio minaccioso incombeva sul paesaggio, privo di qualsiasi segno di vita o di movimento, e desolato e freddo al punto da non poter ispirare che un solo sentimento: quello della più triste malinconia. E nello stesso tempo pareva che da quel paesaggio trapelasse una specie di riso, un riso ben più spaventoso di qualsiasi malinconia o tristezza, un riso tragico, come quello di una sfinge, un riso agghiacciante più della brina e che rammendava l'incombere minaccioso dell'ineluttabile. Era la saggezza potente e impenetrabile dell'eternità che irrideva alla vita, alla sua futilità e agli sforzi degli uomini.

  4. #4
    Utente di HTML.it L'avatar di Gabbro
    Registrato dal
    Nov 2000
    Messaggi
    828
    Originariamente inviato da luca200
    A occhio e croce direi che peggioreresti le cose

    Il campo id_mittente non ha un indice?
    dici che con l'array rallenterei ancora di + le cose?
    si il campo id_mittente è indicizzato.

  5. #5
    Utente di HTML.it L'avatar di Gabbro
    Registrato dal
    Nov 2000
    Messaggi
    828
    Originariamente inviato da IroN@xiD
    Se invece di visualizzare gli ultimi dieci e così via visualizzi i messaggi per settimane o giorni e quindi attraverso il WHERE filtri con un data<ora AND data>ieri mysql dovrà ordinare un numero drasticamente minore di record.

    Per come agisci tu adesso mysql fa questi passaggi (almeno per quanto ne so).

    -prende TUTTI i record che corrispondono col WHERE (e sono tutti i messaggi dell'utente dall'alba dei tempi)
    -li ordina (TUTTI)
    -prende i primi 10

    Se tu agisci per data invece succede questo
    -prende i messaggi mandati entro un determinato periodo
    -ordina SOLO quelli
    -se vuoi puoi prendere i primi 10 nel caso ce ne fossero di più nel periodo trattato

    capisco... però il fatto è che il campo data è un datetime. se io metto nella query una condizione su data non rischio di rallentare ancora di + il tutto?

  6. #6
    Utente di HTML.it L'avatar di luca200
    Registrato dal
    Apr 2002
    Messaggi
    4,120
    quante righe ha questa tabella?

  7. #7
    Utente di HTML.it L'avatar di Gabbro
    Registrato dal
    Nov 2000
    Messaggi
    828
    Originariamente inviato da luca200
    quante righe ha questa tabella?
    un milione

  8. #8
    Utente di HTML.it L'avatar di thepooh
    Registrato dal
    Oct 2005
    Messaggi
    203
    più stringata di così la query non si può eseguire, l'unica cosa per velocizzare è inserire gli indici sui campi che richiedi, ma se ho capito il campo id lo è già.
    Puoi provare degli stratagemmi.
    1)Dai una pagina intermedia fra la domanda e la risposta, il tempo rimarrà sempre uguale, ma l'utente si vede visualizzare due pagine e non gli sembrerà di attendere.
    2)Dividi le tabelle, ogni 5-10 mila id crei ne crei una. Statisticamente a lungo andare avranno un ciclo uguale di record, in pratica crei delle tabelle completamente uguali nei campi, ma quando vai a leggere, inserire o modificare un dato lo suddividi su una tabella in base al numero id. Ti puoi portare dietro la variabile in una globale o ogni volta che accedi al db leggi uno script con la trascodifica.

  9. #9
    Originariamente inviato da Gabbro
    capisco... però il fatto è che il campo data è un datetime. se io metto nella query una condizione su data non rischio di rallentare ancora di + il tutto?
    Secondo me no. Poi ti conviene provare, basta che dai qualche sql direttamente da console per vedere se ho ragione oppure no.

    Ma così a primo impatto direi che non puoi rallentare.
    Perchè tanto tu finisci per fare cmq un operazione sul campo data quando crei l'ordinamento con la query attuale (e lo fai sempre per tutti i record dell'utente) con l'aggravio maggiore di dover anche fare l'ordinamento.

    Edit: mi sono accorto che non ordinavi sulla data. Quindi quello che ho scritto sopra a proposito dell'operazione non conta.

    Poi, a discapito di altre ipotesi più catastrofiche, puoi anche decidere di lavorare con i timestamp (sempre che tu possa farlo).

    Fai una prova con qualche query da console.

    Edit2: se decidi di provare la tua proposta iniziale puoi usare data_seek. Inoltre mi chiedevo, ma sul limit non si può usare un valore fornito da sql? Conti i record trovati con where e ti fai restituire solo gli ultimi 10 così skippi l'ordinamento?
    Lungo le due rive del fiume gelato si stendeva la cupa e tetra foresta di abeti, dai quali il vento aveva appena spazzato il manto di brina. Nella luce crepuscolare quegli abeti neri e sinistri sembravano inclinarsi l'uno verso l'altro. Un silenzio minaccioso incombeva sul paesaggio, privo di qualsiasi segno di vita o di movimento, e desolato e freddo al punto da non poter ispirare che un solo sentimento: quello della più triste malinconia. E nello stesso tempo pareva che da quel paesaggio trapelasse una specie di riso, un riso ben più spaventoso di qualsiasi malinconia o tristezza, un riso tragico, come quello di una sfinge, un riso agghiacciante più della brina e che rammendava l'incombere minaccioso dell'ineluttabile. Era la saggezza potente e impenetrabile dell'eternità che irrideva alla vita, alla sua futilità e agli sforzi degli uomini.

  10. #10
    Utente di HTML.it L'avatar di Gabbro
    Registrato dal
    Nov 2000
    Messaggi
    828
    Originariamente inviato da IroN@xiD
    Secondo me no. Poi ti conviene provare, basta che dai qualche sql direttamente da console per vedere se ho ragione oppure no.

    Ma così a primo impatto direi che non puoi rallentare.
    Perchè tanto tu finisci per fare cmq un operazione sul campo data quando crei l'ordinamento con la query attuale (e lo fai sempre per tutti i record dell'utente) con l'aggravio maggiore di dover anche fare l'ordinamento.

    Edit: mi sono accorto che non ordinavi sulla data. Quindi quello che ho scritto sopra a proposito dell'operazione non conta.

    Poi, a discapito di altre ipotesi più catastrofiche, puoi anche decidere di lavorare con i timestamp (sempre che tu possa farlo).

    Fai una prova con qualche query da console.

    Edit2: se decidi di provare la tua proposta iniziale puoi usare data_seek. Inoltre mi chiedevo, ma sul limit non si può usare un valore fornito da sql? Conti i record trovati con where e ti fai restituire solo gli ultimi 10 così skippi l'ordinamento?
    ciao,
    avevi ragione.
    ho provato una query di questo tipo:
    SELECT id, mittente, oggetto , data from messaggi where id_mittente = 18145 and fl<>2 and date > '2005-10-01 16:20:15' ORDER BY id DESC limit 0, 10
    ovvero mostro solo le date dopo quella data e la query risulta molto + veloce perchè ha meno records da ordinare come dicevi tu. ma se io ora mettessi un indice su date la query potrebbe risultare ancora + veloce?

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.