Kalle_B: MySQL SQL_CALC_FOUND_ROWS verzögert gewaltig

Hallöle,

wenn ich mir die ersten 50 Sätze aus der Geo-Datenbank (8178 Sätze) anzeigen lasse, dauert das gewaltige 24 sec mit SQL_CALC_FOUND_ROWS:

SELECT
 SQL_CALC_FOUND_ROWS
 ort1.*
FROM      bia_orte AS ort1
ORDER BY ort1.name, ort1.name_zusatz
LIMIT 0,50

ohne SQL_CALC_FOUND_ROWS, aber mit zusätzlicher Abfrage

SELECT count(*)
FROM      bia_orte AS ort1

nur 0,15 sec

Warum ist der SQL_CALC_FOUND_ROWS um Potenzen langsamer als count?

MfG Kalle

P.S. Habe einen Key gesetzt auf ort1.name, ort1.name_zusatz, hat aber nichts gebracht.

  1. Hallo Kalle,

    wenn ich mir die ersten 50 Sätze aus der Geo-Datenbank (8178 Sätze) anzeigen lasse, dauert das gewaltige 24 sec mit SQL_CALC_FOUND_ROWS:

    Warum ist der SQL_CALC_FOUND_ROWS um Potenzen langsamer als count?

    Lies bitte
    http://dev.mysql.com/doc/refman/5.0/en/limit-optimization.html
    http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_count

    Es steht dort.

    Freundliche Grüße

    Vinzenz

  2. Hi Kalle,

    SELECT
    SQL_CALC_FOUND_ROWS
    ort1.*
    FROM      bia_orte AS ort1
    ORDER BY ort1.name, ort1.name_zusatz
    LIMIT 0,50

    neben den von Vinzenz verlinkten Hinweisen: du sortierst hier nach zwei Spalten. Um dort einen Index nutzen zu können, benötigt MySQL einen Multiple-Column Index über beiden Spalten. Ansonsten gibt es einen Full Table Scan, den man in jedem Fall vermeiden möchte. Ich vermute, dass du nur einen Index über jeweils eine Spalte gesetzt hast!? Es wäre hilfreich, wenn du mal die Ausgabe von

    SHOW CREATE TABLE bia_orte;

    posten würdest. In jedem Fall lohnt es sich aber, dir die Ausgabe von EXPLAIN anzusehen:

    EXPLAIN SELECT SQL_CALC_FOUND_ROWS ort1.*  
    FROM bia_orte AS ort1  
    ORDER BY ort1.name, ort1.name_zusatz  
    LIMIT 0,50;
    

    Wenn in der Spalte "type" der Wert "ALL" auftaucht, hast du einen Full Table Scan produziert => nicht gut. Das gleiche EXPLAIN-Ergebnis dürftest du übrigens auch ohne SQL_CALC_FOUND_ROWS erhalten; dass die Query dann trotzdem so "schnell" arbeitet, dürfte daran liegen, dass MySQL wegen der LIMIT-Angabe nach 50 gefundenen Zeilen abbricht, was es mit SQL_CALC_FOUND_ROWS nicht tut.

    Gruß,
    Andreas.