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.
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).
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
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");
Ich habe immer verstanden, dass ich mit den folgenden Angaben am schnellsten reagieren kann.
SELECT COUNT(1) FROM ... WHERE ...
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 |
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.
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
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.
Versuche dies:
SELECT
table_rows "Rows Count"
FROM
information_schema.tables
WHERE
table_name="Table_Name"
AND
table_schema="Database_Name";
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.
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 ...
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.