2017-04-11 3 views
1

Ich habe eine Frage zu einer Mysql-Abfrage.Limit-Abfrage kann nicht wirksam sein

Ich habe einige langsame Abfragen. Hier ist einer von ihnen:

SELECT 
    xxx_accounts.id 
    , xxx_accounts.name 
    , xxx_accounts.account_name 
    , xxx_accounts.address_postalcode 
    , xxx_accounts.address_city 
    , xxx_accounts.address_state 
    , xxx_accounts.date_modified 
    , xxx_accounts.assigned_user_id 
FROM 
    xxx_accounts 
WHERE 
    xxx_accounts.deleted = 0 
ORDER BY 
    xxx_accounts.date_entered DESC 
LIMIT 4434950, 11; 

Es dauert fast 2 Minuten, auch wenn es Limit-Abfrage verwenden. Erklären

ist hier:

+----+-------------+--------------+------+--------------------------------------------------------------------------------+-------------------------+---------+-------+---------+-------------+      
| id | select_type | table  | type | possible_keys                 | key      | key_len | ref | rows | Extra  | 
+----+-------------+--------------+------+--------------------------------------------------------------------------------+-------------------------+---------+-------+---------+-------------+ 
| 1 | SIMPLE  | xxx_accounts | ref | idx_deleted_datemodified,idx_deleted_addresspostalcode,idx_deleted_dateentered | idx_deleted_dateentered | 2  | const | 1861322 | Using where | 
+----+-------------+--------------+------+--------------------------------------------------------------------------------+-------------------------+---------+-------+---------+-------------+ 

Dies sagte zu erklären, dass Zeilen Gesamtzahl ist.

Allerdings ist diese SQL geändert Grenze "" Abfrage, LIMIT 1,11 ", es dauert ein paar Sekunden (wie 1 oder 2 Sekunden). Der Unterschied dieser SQL liegt zwischen LIMIT 4434950,11 und LIMIT 1,11.

Kann dieses Problem irgendwie gelöst werden?

+0

Wie wissen Sie, dass Sie in den ersten 4.434.950 Zeilen nicht interessiert sind, wenn sie von Datum geordnet? – Strawberry

+0

Es tut mir leid. Ich kann Ihre Frage nicht verstehen. Bitte erklären Sie mehr Details. –

Antwort

2

Verstehen Sie den Unterschied zwischen den beiden Grenzen:

"LIMIT 1,11": bedeutet, dass Sie nur 1 Datensatz von 11 versetzt beginnen, werden zu holen.

"LIMIT 4434950,11": bedeutet, dass Sie 4434950 Datensätze ab 11 Offset abrufen. In dieser Abfragetabelle wird tausende Zeilen abgetastet, um 4434950 Datensätze zu erhalten, und dann stoppt es, es wird definitiv mehr Zeit und Ressourcen benötigen, da das Ergebnis auch viele Zeilen enthält.

Es ist normal, dass höhere Offsets die Abfrage verlangsamen, da die Abfrage die ersten OFFSET + LIMIT-Datensätze abzählen muss (und nur LIMIT von ihnen nimmt). Je höher dieser Wert ist, desto länger wird die Abfrage ausgeführt.

Die Abfrage kann nicht direkt zu OFFSET wechseln, da die Datensätze zum einen unterschiedlich lang sein können und zum anderen Lücken von gelöschten Datensätzen bestehen können. Es muss jeden Datensatz auf seinem Weg überprüfen und zählen.

Einige Tricks macht diese Abfrage schnell:

MySQL nicht direkt an den 10000. Datensatz gehen kann (oder 80000. Byte als was darauf hindeutet), weil sie nicht davon ausgehen können, dass es so vollgepackt/bestellt (oder dass es hat kontinuierliche Werte in 1 bis 10000). Obwohl es in Wirklichkeit so sein kann, kann MySQL nicht davon ausgehen, dass es keine Lücken/Lücken/gelöschten IDs gibt.

So

SELECT * FROM large ORDER BY id LIMIT 10000, 30 

würde langsam (er),

SELECT * FROM large WHERE id > 10000 ORDER BY id LIMIT 30 

würde schnell sein (er), und würden wieder die gleichen Ergebnisse vorausgesetzt, dass es keine fehlenden IDs sind (dh Lücken).

Very good explanation here

+0

Danke.Ich verstehe. –

+0

das heißt, ist es nicht vermeidbar noch 1 Minute? –

+1

Es ist möglich, durch Abfrage-Optimierung.Überprüfen Sie diesen Link: http://stackoverflow.com/questions/4481388/why-does-mysql-higher-limit-offset-slow-the-query-down –