Wenn Sie die Anzahl der Zeilen begrenzen, die von einer SQL-Abfrage zurückgegeben werden sollen, die normalerweise beim Paging verwendet wird, gibt es zwei Methoden, um die Gesamtzahl der Datensätze zu bestimmen:
Methode 1
Fügen Sie die SQL_CALC_FOUND_ROWS
Option in das Original ein SELECT
und ermitteln Sie die Gesamtzahl der Zeilen, indem Sie Folgendes ausführen SELECT FOUND_ROWS()
:
SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
Methode 2
Führen Sie die Abfrage normal aus, und ermitteln Sie dann die Gesamtzahl der Zeilen, indem Sie sie ausführen SELECT COUNT(*)
SELECT * FROM table WHERE id > 100 LIMIT 10;
SELECT COUNT(*) FROM table WHERE id > 100;
Welche Methode ist die beste / schnellste?
quelle
SQL_CALC_FOUND_ROWS
dauerte über 20 Sekunden. Die Verwendung einer separatenCOUNT(*)
Abfrage dauerte weniger als 5 Sekunden (für beide Abfragen mit Anzahl + Ergebnisse).SQL_CALC_FOUND_ROWS
schneller sein, frage ich mich , in welchen Situationen (wenn überhaupt) es tatsächlich ist schneller!tblA
,tblB
,tblC
,tblD
, ,tblY
WO tblA.b = tblC.id UND tblA.c = tblB.id UND tblA.d = tblD.id UND tblA.y = tblY.idid
) ausführte, dauerte es allein 0,25.FOUND_ROWS()
Beachten Sie zusätzlich zu möglichen Leistungsproblemen, dass dies in MySQL 8.0.17 veraltet ist. Siehe auch die Antwort von @ madhur-bhaiya.Bei der Auswahl des "besten" Ansatzes ist möglicherweise die Wartbarkeit und Korrektheit Ihres Codes wichtiger als die Geschwindigkeit. In diesem Fall ist SQL_CALC_FOUND_ROWS vorzuziehen, da Sie nur eine einzige Abfrage verwalten müssen. Die Verwendung einer einzelnen Abfrage schließt die Möglichkeit eines geringfügigen Unterschieds zwischen der Haupt- und der Zählabfrage vollständig aus, was zu einer ungenauen Zählung führen kann.
quelle
MySQL hat begonnen, die
SQL_CALC_FOUND_ROWS
Funktionalität ab Version 8.0.17 zu verwerfen.Es wird daher immer bevorzugt , die Ausführung Ihrer Abfrage mit
LIMIT
und anschließend eine zweite Abfrage mitCOUNT(*)
und ohne in Betracht zu ziehen,LIMIT
um festzustellen, ob zusätzliche Zeilen vorhanden sind.Aus Dokumenten :
Es wurde auch
SQL_CALC_FOUND_ROWS
beobachtet, dass allgemein mehr Probleme auftreten, wie in MySQL WL # 12615 erläutert :quelle
LOCK TABLES <tablename>
und zu umgebenUNLOCK TABLES
. Die dritte Option und (meiner Meinung nach am besten) besteht darin, die Paginierung zu überdenken. Bitte lesen Sie: mariadb.com/kb/en/library/pagination-optimizationLaut folgendem Artikel: https://www.percona.com/blog/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
Wenn Sie einen INDEX für Ihre where-Klausel haben (wenn in Ihrem Fall die ID indiziert ist), ist es besser, nicht SQL_CALC_FOUND_ROWS zu verwenden und stattdessen zwei Abfragen zu verwenden, aber wenn Sie keinen Index für das haben, was Sie in Ihre where-Klausel einfügen (ID in Ihrem Fall) Die Verwendung von SQL_CALC_FOUND_ROWS ist dann effizienter.
quelle
IMHO, der Grund, warum 2 Anfragen
sind schneller als mit SQL_CALC_FOUND_ROWS
muss als besonderer Fall gesehen werden.
Tatsächlich hängt es von der Selektivität der WHERE-Klausel im Vergleich zur Selektivität der impliziten Klausel ab, die der ORDER + LIMIT entspricht.
Wie Arvids in einem Kommentar ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-1174394 ) sagte , die Tatsache, dass die EXPLAIN verwenden oder nicht. Eine temporäre Tabelle sollte eine gute Grundlage sein, um zu wissen, ob SCFR schneller ist oder nicht.
Aber wie ich hinzugefügt habe ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-8166482 ), hängt das Ergebnis wirklich wirklich vom Fall ab. Für einen bestimmten Paginator könnten Sie zu dem Schluss kommen, dass „für die drei ersten Seiten zwei Abfragen verwendet werden; Verwenden Sie für die folgenden Seiten einen SCFR “!
quelle
Entfernen Sie unnötiges SQL und gehen Sie dann
COUNT(*)
schneller alsSQL_CALC_FOUND_ROWS
. Beispiel:Dann zählen Sie ohne unnötigen Teil:
quelle
Es gibt andere Optionen für das Benchmarking:
1.) Eine Fensterfunktion gibt die tatsächliche Größe direkt zurück (getestet in MariaDB):
2.) Wenn Benutzer über den Tellerrand hinaus denken, müssen sie die genaue Größe der Tabelle meistens nicht kennen. Eine ungefähre Größe ist oft gut genug.
quelle