2009-05-19 13 views
16

Ecco la query (la tabella più grande ha circa 40.000 righe)query lente quando si utilizza ORDER BY

SELECT 
    Course.CourseID, 
    Course.Description, 
    UserCourse.UserID, 
    UserCourse.TimeAllowed, 
    UserCourse.CreatedOn, 
    UserCourse.PassedOn, 
    UserCourse.IssuedOn, 
    C.LessonCnt 
FROM 
    UserCourse 
INNER JOIN 
    Course 
USING(CourseID) 
INNER JOIN 
(
    SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID 
) C 
USING(CourseID) 
WHERE 
    UserCourse.UserID = 8810 

Se corro questo, esegue molto rapidamente (.05 secondi circa). Restituisce 13 righe.

Quando aggiungo una clausola ORDER BY alla fine della query (ordinando per qualsiasi colonna) la query impiega circa 10 secondi.

Attualmente sto utilizzando questo database in produzione e tutto funziona correttamente. Tutte le mie altre domande sono veloci.

Qualche idea di cosa potrebbe essere? Ho eseguito la query nel browser Query di MySQL e dalla riga di comando. Entrambi i posti è stato lento con il ORDER BY.

MODIFICA: Tolgahan La soluzione ALBAYRAK funziona, ma qualcuno può spiegare perché funziona?

+0

Perché funziona? una sottoquery prende il risultato in una serie di risultati e l'ordinamento di un set di risultati è molto più rapido di quello che l'esecuzione della query predefinita ha il conteggio in ordine lungo la strada. –

risposta

15

forse questo aiuta:

SELECT * FROM ( 
    SELECT 
     Course.CourseID, 
     Course.Description, 
     UserCourse.UserID, 
     UserCourse.TimeAllowed, 
     UserCourse.CreatedOn, 
     UserCourse.PassedOn, 
     UserCourse.IssuedOn, 
     C.LessonCnt 
    FROM 
     UserCourse 
    INNER JOIN 
     Course 
    USING(CourseID) 
    INNER JOIN 
    (
     SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID 
    ) C 
    USING(CourseID) 
    WHERE 
     UserCourse.UserID = 8810 
) ORDER BY CourseID 
+0

Huh, funziona (lo rende veloce). Sai perché però? Non ho mai dovuto farlo prima. –

+0

40k non è che molti record; in genere devono fare i conti con milioni di volte che la tua milizia può variare, ma ciò potrebbe contribuire a migliorare ulteriormente le prestazioni in quanto i join verranno effettuati su un set di dati ridotto. ... DA (select * from UserCourse Dove UserID = 8810 ) UserCourse – u07ch

+0

@Dude - il rallentamento viene perché è probabilmente la scelta di fare l'ordine prima di fare il join. L'esecuzione dell'ordine in una query esterna obbliga a ordinare solo gli elementi selezionati. – tvanfosson

6

La colonna che stai ordinando per indicizzazione?

L'indicizzazione aumenta drasticamente l'ordine e il filtraggio.

+0

l'op menzionato utilizzando qualsiasi colonna nell'ordine riduce le prestazioni – northpole

+1

Qualsiasi colonna, incluse le colonne indicizzate, la rendono lenta. –

0

Avete aggiornato le statistiche sul vostro database? Mi sono imbattuto in qualcosa di simile sul mio dove avevo due domande identiche in cui l'unica differenza era una lettera maiuscola e una restituita in 1/2 secondo e l'altra impiegava circa 5 minuti. Aggiornamento delle statistiche risolto il problema

0

Una domanda simile è stato chiesto prima here.

Potrebbe aiutare pure. Fondamentalmente descrive l'utilizzo di indici compositi e di come ordinare per lavori.

0

Oggi mi sono imbattuto in uno stesso tipo di problema. Non appena stavo ordinando il set di risultati da un campo di una tabella unita, l'intera query era terribilmente lenta e richiedeva più di cento secondi.

Il server eseguiva MySQL 5.0.51a e per caso ho notato che la stessa query era in esecuzione veloce come avrebbe dovuto sempre fare su un server con MySQL 5.1. Quando ho confrontato le spiegazioni per quella query, ho visto che ovviamente l'uso e la gestione degli indici è cambiato molto (almeno da 5.0 -> 5.1).

Quindi, se si verifica un problema, forse la risoluzione è quello di aggiornare semplicemente il vostro MySQL

1

Realizza risposta è troppo tardi, ma ho appena avuto un problema simile, aggiungendo ordine da un aumento del tempo di risposta da secondi a 5 minuti e dopo aver provato la maggior parte degli altri suggerimenti per velocizzarlo, ho notato che i file/tmp dove arrivare a essere 12G per questa query. Modificata la query in modo tale che un campo varchar (20000) restituito fosse "trim (" ed e le prestazioni migliorate drasticamente (di nuovo in secondi). Quindi credo che valga la pena di verificare se si stanno restituendo varchar di grandi dimensioni come parte della query e, in tal caso, elaborali (magari sottostringa (x, 1, lunghezza (x)) ?? se non vuoi ritagliarli. Query restituiva 500k righe e il file/tmp indicava che ogni riga stava usando circa 20k di dati.

1

Si sta selezionando da "UserCourse" che presumo sia una tabella di unione tra corsi e utenti (da molti a molti). Dovresti indicizzare la colonna che devi ordinare, nella tabella "UserCourse".

si supponga di voler "ordine da CourseID", allora avete bisogno di indice su UserCourse tavolo.

Ordinare da qualsiasi altra colonna che non è presente nella tabella di unione (ad esempio UserCourse) può richiedere ulteriore denormalizzazione e indicizzazione sulla tabella di unione da ottimizzare per la velocità; In altre parole, è necessario avere una copia di quella colonna nella tabella di unione e indicizzarla.

P.S. La risposta data da Tolgahan Albayrak, sebbene corretta per questa domanda, non produrrebbe il risultato desiderato, nei casi in cui si sta facendo una query "LIMIT x".

Problemi correlati