it-swarm.com.de

MySQL: Schnellster Weg, um die Anzahl der Zeilen zu zählen

Welcher Weg, um mehrere Zeilen zu zählen, sollte in MySQL schneller sein?

Diese:

SELECT COUNT(*) FROM ... WHERE ...

Oder die Alternative:

SELECT 1 FROM ... WHERE ...

// and then count the results with a built-in function, e.g. in PHP mysql_num_rows()

Man könnte meinen, dass die erste Methode schneller sein sollte, da dies eindeutig Datenbankgebiet ist und die Datenbank-Engine bei der Bestimmung solcher Dinge intern schneller als jeder andere sein sollte.

101
Franz

Wenn Sie COUNT(*) die Spaltenindizes zählen, wird dies das beste Ergebnis sein. Mysql mit MyISAM engine speichert tatsächlich die Zeilenanzahl. Es werden nicht alle Zeilen gezählt, wenn Sie versuchen, alle Zeilen zu zählen. (basierend auf der Spalte des Primärschlüssels)

Die Verwendung von PHP zum Zählen von Zeilen ist nicht sehr intelligent, da Sie Daten von MySQL an PHP senden müssen. Warum tun Sie es, wenn Sie dasselbe auf der MySQL-Seite erreichen können?

Wenn COUNT(*) langsam ist, sollten Sie EXPLAIN für die Abfrage ausführen und prüfen, ob Indizes wirklich verwendet werden und wo sie hinzugefügt werden sollen.


Das Folgende ist nicht der schnellste Weg, aber es gibt einen Fall, in dem COUNT(*) nicht wirklich passt. Wenn Sie mit dem Gruppieren von Ergebnissen beginnen, können Sie auf ein Problem stoßen, in dem COUNT nicht wirklich alle Zeilen zählt.

Die Lösung ist SQL_CALC_FOUND_ROWS. Dies wird normalerweise verwendet, wenn Sie Zeilen auswählen, aber die Gesamtzahl der Zeilen kennen müssen (z. B. für Paging) .. Wenn Sie Datenzeilen auswählen, hängen Sie einfach das Schlüsselwort SQL_CALC_FOUND_ROWS nach SELECT an:

SELECT SQL_CALC_FOUND_ROWS [needed fields or *] FROM table LIMIT 20 OFFSET 0;

Nachdem Sie die erforderlichen Zeilen ausgewählt haben, können Sie die Anzahl mit dieser einzelnen Abfrage ermitteln:

SELECT FOUND_ROWS();

FOUND_ROWS() muss unmittelbar nach der Datenauswahlabfrage aufgerufen werden.


Im Endeffekt kommt es tatsächlich darauf an, wie viele Einträge Sie haben und was in der WHERE-Anweisung enthalten ist. Sie sollten wirklich darauf achten, wie Indizes verwendet werden, wenn es viele Zeilen gibt (Zehntausende, Millionen und mehr).

112

Nachdem Ricardo mit meinen Teamkollegen gesprochen hatte, sagte er uns, dass der schnellere Weg ist:

show table status like '<TABLE NAME>' \G

Sie müssen jedoch bedenken, dass das Ergebnis möglicherweise nicht genau ist.

Sie können es auch von der Kommandozeile aus verwenden:

$ mysqlshow --status <DATABASE> <TABLE NAME>

Weitere Informationen: http://dev.mysql.com/doc/refman/5.7/de/show-table-status.html

Eine vollständige Diskussion finden Sie unter mysqlperformanceblog

44
MagMax

Tolle Frage, tolle Antworten. Hier ist eine schnelle Methode, um die Ergebnisse wiederzugeben, wenn jemand diese Seite liest und diesen Teil vermisst:

$counter = mysql_query("SELECT COUNT(*) AS id FROM table");
$num = mysql_fetch_array($counter);
$count = $num["id"];
echo("$count");
30
Dan Horvat

Ich habe immer verstanden, dass ich mit den folgenden Angaben am schnellsten reagieren kann.

SELECT COUNT(1) FROM ... WHERE ...
13
adarshr

Diese Abfrage (ähnlich der von bayuah geposteten) zeigt eine schöne Zusammenfassung aller Tabellen in einer Datenbank: (Vereinfachte Version der gespeicherten Prozedur von Ivan Cachicatari die ich sehr empfehle).

SELECT TABLE_NAME AS 'Table Name', TABLE_ROWS AS 'Rows' FROM information_schema.TABLES WHERE TABLES.TABLE_SCHEMA = 'YOURDBNAME' AND TABLES.TABLE_TYPE = 'BASE TABLE'

Beispiel: 

+-----------------+---------+ | Table Name | Rows | +-----------------+---------+ | some_table | 10278 | | other_table | 995 |

13
lepe

Wenn Sie die Anzahl der gesamten Ergebnismenge abrufen möchten, können Sie folgende Vorgehensweise verwenden:

SELECT SQL_CALC_FOUND_ROWS * FROM table_name LIMIT 5;
SELECT FOUND_ROWS();

Dies ist normalerweise nicht schneller als die Verwendung von COUNT. Allerdings könnte man annehmen, dass das Gegenteil der Fall ist, da die Berechnung intern erfolgt und die Daten nicht an den Benutzer zurückgeschickt werden.

Diese beiden Abfragen sind für die Paginierung von Summen, nicht aber für die Verwendung von WHERE-Klauseln gut.

6
infinity

Ich habe einige Benchmarks durchgeführt, um die Ausführungszeit von COUNT(*) mit COUNT(id) zu vergleichen (id ist der Primärschlüssel der Tabelle - indiziert).

Anzahl von Versuchen: 10 * 1000 Anfragen

Ergebnisse: COUNT(*) ist schneller 7%

GRAFIK ANZEIGEN: Benchmarkgraph

Mein Rat ist zu verwenden: SELECT COUNT(*) FROM table

5
SamC

Vielleicht möchten Sie eine SELECT max(Id) - min(Id) + 1 in Betracht ziehen. Dies funktioniert nur, wenn Ihre IDs sequentiell sind und Zeilen nicht gelöscht werden. Es ist jedoch sehr schnell.

1
sky-dev

Versuche dies:

SELECT
    table_rows "Rows Count"
FROM
    information_schema.tables
WHERE
    table_name="Table_Name"
AND
    table_schema="Database_Name";
1
bayuah

Ich habe Tabellen für die deutsche Regierung mit manchmal 60 Millionen Datensätzen bearbeitet. 

Und wir mussten viele Male die Gesamtzahl der Zeilen kennen.

Wir Datenbankprogrammierer haben also entschieden, dass in jeder Tabelle immer der Datensatz steht, in dem die Gesamtanzahl der Datensätze gespeichert ist. Wir haben diese Anzahl in Abhängigkeit von INSERT- oder DELETE-Zeilen aktualisiert.

Wir haben alle anderen Möglichkeiten ausprobiert. Dies ist bei weitem der schnellste Weg.

1
Scoobeedo Cool

Eine count (*) - Anweisung mit einer where-Bedingung für den Primärschlüssel hat die Zeilenzahl für mich viel schneller zurückgegeben, wobei der vollständige Tabellenscan vermieden wurde.

SELECT COUNT(*) FROM ... WHERE <PRIMARY_KEY> IS NOT NULL;

Das war für mich viel schneller als

SELECT COUNT(*) FROM ...
0
ayakout

EXPLAIN SELECT id FROM .... hat den Trick für mich gemacht. und ich konnte die Anzahl der Zeilen in der Spalte rows des Ergebnisses sehen.

0
ssrp