2011-08-18 14 views
6

Hi ho una tabella db records 7milion per testare la velocità di query.QUERY speed with limit e milion records

Ho testato i miei 2 domande che sono la stessa query con diversi parametri limite:

interrogazione 1 -

SELECT * 
FROM  table 
LIMIT  20, 50; 

interrogazione 2 -

SELECT * 
FROM  table 
LIMIT  6000000, 6000030; 

tempi di query exec sono:

  1. query 1 - 0.006 sec
  2. interrogazione 2-5,500 sec

In entrambe queste domande, io sono il recupero stesso numero di record, ma nel secondo caso sta prendendo più tempo. Qualcuno può spiegare le ragioni alla base di questo?

+0

Avete indicizzazione? Hai una chiave primaria? Se non ne hai, questo ha senso per me. –

+0

@amir se nessuna indicizzazione per entrambe le query deve essere lo stesso test no? o se ho messo la seconda query dell'indice richiederà lo stesso tempo della prima query? – sbaaaang

+0

se non hai alcun indice allora non credo che MySQL possa saltare le prime 6000000 righe. Devi avere almeno un indice primario per saltare le righe. Forse qualcun altro può confermarlo? Potremmo anche testarlo. –

risposta

8

Senza guardarlo troppo da vicino, il mio presupposto è che ciò si verifica perché la prima query deve solo leggere sul 50 ° record per restituire i risultati, mentre la seconda query deve leggere sei milioni prima di restituire i risultati. Fondamentalmente, la prima query è subito più veloce.

Parto dal presupposto che questo ha una quantità incredibile a che fare con la composizione del tavolo - tipi di campo e chiavi, ecc

Se un record è composto da campi a lunghezza fissa (ad esempio CHAR VARCHAR vs.), quindi il DBMS può solo calcolare dove inizia l'ennesimo record e salta lì. Se la sua lunghezza variabile, allora si dovrebbe leggere i record per determinare dove inizia l'ennesimo record. Allo stesso modo, assumerei ulteriormente che le tabelle che hanno chiavi primarie appropriate sarebbero più veloci da interrogare rispetto a quelle senza tali chiavi.

+0

questo è quello che penso di sicuro: (e penso che nessuna soluzione per quello giusto? Solo query caching :( – sbaaaang

+1

@user Non riesco a pensare a una soluzione in cima alla mia testa. L'unica cosa che potrei pensare - e questo è un ** hack totale ** - sarebbe aggiungere un campo datetime per contrassegnare la creazione del record, quindi aggiungi un indice su quel campo e poi ordina su quel campo nella query. Non l'ho provato, ma tu ** potresti ** essere in grado di ingannare il database per limitare basato su quella chiave, che potrebbe far funzionare la query in O (1) volta, ma non ci conterei, inoltre non è esattamente la query che hai sopra, perché l'ordinamento predefinito non è definito dalle specifiche: dovresti emulare una convenzione piuttosto che una specifica; YMMV. – AgentConundrum

+0

grazie per l'hack proverò smethings comunque stavo solo chiedendo le differenze per capisci meglio come mysql process db records;) – sbaaaang

6

Penso che il rallentamento sia legato al fatto che si stanno usando limiti con offset e si sta interrogando la tabella senza alcun contesto aggiuntivo per l'indicizzazione. È possibile che il primo sia solo più veloce perché può raggiungere l'offset più rapidamente.

+1

alcuni googling suggeriscono che mysql conta ogni riga fino a raggiungere l'offset .. quindi indovinare ci vuole più tempo per arrivare al più xxxxx rispetto alla 20 ° riga. –

+0

che è indicizzazione vera non c'è ma non è un problema di velocità mi stavo solo chiedendo della differenza;) – sbaaaang

4

È la differenza tra il ritorno di 50 righe e 6000030 righe (o ~ 1 milione di righe da quando hai detto che c'erano solo 7 milioni di righe).

Con due argomenti, il primo argomento specifica l'offset della prima fila tornare, e il secondo specifica il numero massimo di righe per tornare. Lo scostamento della riga iniziale è 0 (non 1):

SELECT * FROM tbl LIMIT 5,10; # Recuperare le righe 6-15

http://dev.mysql.com/doc/refman/5.0/en/select.html

Inoltre, penso che siete alla ricerca di 30 pagine di fila in modo che le domande dovrebbero utilizzare 30 come secondo parametro nella clausola limite.

SELECT * 
FROM  table 
LIMIT  20, 30; 

SELECT * 
FROM  table 
LIMIT  6000000, 30; 
+0

Il secondo parametro potrebbe essere un fattore che contribuisce perché la query sta di fatto restituendo molte più righe .. Non penso che sia giusto dire che questo non fornisce una risposta .. la sua risposta è che la restituzione di un file di bajillion richiede più tempo .. e probabilmente è parzialmente corretta. –

+0

ok ... quindi anche i record in tale intervallo vengono analizzati o saltati? penso che siano analizzati o non ci sarà differenza, mentre la differenza esiste, giusto? Lo spostamento – sbaaaang

+0

è minimo rispetto al conteggio delle righe. \t Stavo scavando il riferimento – dotjoe