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

    Evitare filesort con COUNT

    Salve ragazzi,
    ho due tabelle: NEWS e COMMENTS e creo una tabella che mi raccolga le notizie più commentate così:

    codice:
    SELECT NEWS.ID_NEWS,
        (SELECT COUNT(*) FROM COMMENTS WHERE NEWS.ID_NEWS = COMMENTS.ID_NEWS) AS NUM_COMMENTI
    FROM NEWS
    WHERE NEWS.LANG_ita = 0 AND NEWS.TIMESTAMP >= DATE_SUB('2013-01-09', INTERVAL 1 WEEK)
    ORDER BY NUM_COMMENTI DESC
    LIMIT 0,5
    Mi tira fuori correttamente l'id della news e accanto i commenti, sono le ultime 5 ed è tutto giusto. Solo che no ho notato che facendo Explain mi fa un filesort.
    A questo punto mi chiedo, dato che mi sto scervellando da tutta la sera, è inevitabile avere un filesort quando si fa un count e c'è da ordinare le righe?
    Ho messo gli indici sia su News che su Comments ma il problema sta in quell'ORDER BY NUM_COMMENTS, che è un numero che non ho in nessuna tabella fisicamente.

    Grazie mille

  2. #2
    Utente di HTML.it L'avatar di vnt54
    Registrato dal
    Mar 2009
    Messaggi
    500
    ORDER BY NUM_COMMENTS
    E' un errore di trascrizione?non lo vedo da nessuna parte.
    Sono stato nella terra della paura e dei vampiri...in transilvania?NO!..in Banca!

  3. #3
    Originariamente inviato da vnt54
    E' un errore di trascrizione?non lo vedo da nessuna parte.
    si scusami, ovviamente ORDER BY NUM_COMMENTI (creato dalla SELECT)... E per questo ordinando per questa variabile non so come evitare il filesort.... Vi prego sto impazzendo

  4. #4
    metti le due tabelle in JOIN e fai la COUNT / GROUP BY

  5. #5
    Originariamente inviato da optime
    metti le due tabelle in JOIN e fai la COUNT / GROUP BY
    Già provato:

    codice:
    SELECT NEWS.ID_NEWS, COUNT(*) AS NUM_COMMENTI
    FROM NEWS
    INNER JOIN COMMENTS ON NEWS.ID_NEWS = COMMENTS.ID_NEWS
    WHERE NEWS.LANG_ita = 0 AND NEWS.TIMESTAMP >= DATE_SUB('2013-01-09', INTERVAL 1 WEEK)
    GROUP BY NEWS.ID_NEWS
    ORDER BY NUM_COMMENTI DESC
    LIMIT 0,5
    anche:

    codice:
    SELECT NEWS.ID_NEWS, SUM(ISNULL(COMMENTS.ID_NEWS)=0) as NUM_COMMENTI
    FROM NEWS
    INNER JOIN COMMENTS ON COMMENTS.ID_NEWS = NEWS.ID_NEWS
    WHERE NEWS.LANG_ita = 0 AND NEWS.TIMESTAMP >= DATE_SUB('2013-01-09', INTERVAL 1 WEEK)
    GROUP BY NEWS.ID_NEWS
    ORDER BY NUM_COMMENTI DESC
    LIMIT 0,5
    e pure così:

    codice:
    SELECT NEWS.ID_NEWS, tmp.NUM_COMMENTI
    FROM NEWS
    INNER JOIN (SELECT ID_NEWS, COUNT(*) AS NUM_COMMENTI FROM COMMENTS GROUP BY COMMENTS.ID_NEWS) AS tmp
    ON NEWS.ID_NEWS = tmp.ID_NEWS
    WHERE NEWS.LANG_ita = 0 AND NEWS.TIMESTAMP >= DATE_SUB('2013-01-09', INTERVAL 1 WEEK)
    ORDER BY tmp.NUM_COMMENTI DESC
    LIMIT 0,5
    (ma questa va a cercare tra troppe righe)

    funzionano, però in queste maniere peggioro:
    codice:
    Using where; Using temporary; Using filesort
    Nonostante abbia l'indice LANG_ita che comprende ID_NEWS e TIMESTAMP che comprende ID_NEWS

  6. #6
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Posto che l'explain mostra che usi mysql o mariadb, segnalo che l'utilizzo di una subquery dipendente (primo caso) richiede abbastanza ovviamente un file sort.
    Nel secondo invece (join) tipicamente si avrà una temporary table.

    Perchè accade? Accade perchè non esiste un indice sul dato che stai calcolando al volo (il count), in qualsiasi modo lo vuoi generare.
    Pertanto, quando li vuoi ordinare, ci vorrà necessariamente un "meccanismo" per ordinarli DOPO averli ottenuti.

    Non mi è chiarissimo su come ti aspetti che, magicamente, esista un indice (e che quindi non richieda uno stage di ordinamento successivo) su un dato che nel database... non c'è.

    Forse ho capito male?

  7. #7
    Ah ecco, in ogni caso il filesort è obbligatorio quindi..... mi basta questa risposta per mettermi l'anima in pace

  8. #8
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da ..:: T€O ::..
    Ah ecco, in ogni caso il filesort è obbligatorio quindi..... mi basta questa risposta per mettermi l'anima in pace
    In realtà la risposta te l'eri già data
    Ho messo gli indici sia su News che su Comments ma il problema sta in quell'ORDER BY NUM_COMMENTS, che è un numero che non ho in nessuna tabella fisicamente.Solo che non volevi "convincerti"

    Proviamo a ragionare (se ti va) un attimo su come dovrebbe funzionare un ottimizzatore che fa quello che vuoi.

    Cioè tu, intelligente e non stupido come l'elaboratore, riesci a studiare un meccanismo per il quale conti le righe ottenendole ordinate per cardinalità?

    (spero che coglierai l'intento maieutico).

    Se non ci riesci, dubita fortissimamente che qualcosa di stupido come il planner riesca a far meglio (oddio sto dando per scontato che tu abbia più capacità dell'ottimizzatore, questo in generale dipende dall'esperienza)... di te.

  9. #9
    Originariamente inviato da franzauker2.0
    In realtà la risposta te l'eri già data
    Ho messo gli indici sia su News che su Comments ma il problema sta in quell'ORDER BY NUM_COMMENTS, che è un numero che non ho in nessuna tabella fisicamente.Solo che non volevi "convincerti"

    Proviamo a ragionare (se ti va) un attimo su come dovrebbe funzionare un ottimizzatore che fa quello che vuoi.

    Cioè tu, intelligente e non stupido come l'elaboratore, riesci a studiare un meccanismo per il quale conti le righe ottenendole ordinate per cardinalità?

    (spero che coglierai l'intento maieutico).

    Se non ci riesci, dubita fortissimamente che qualcosa di stupido come il planner riesca a far meglio (oddio sto dando per scontato che tu abbia più capacità dell'ottimizzatore, questo in generale dipende dall'esperienza)... di te.
    Eheheheh perfetto, ho colto in pieno

  10. #10
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Per quanto riguarda il tuo problema, in generale, considera se è vantaggioso mantenere brutalmente una tabella con i "top 5", lato programma, o lato trigger.
    Considera che data la natura del limit che hai imposto deve comunque ordinare tutti i risultati, per poi scartarne la maggior parte.
    Ne segue che se il "group by" ha cardinalità relativamente piccola, "paghi" poco o quasi niente per l'ordinamento (e viceversa)

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 © 2026 vBulletin Solutions, Inc. All rights reserved.