Heim Datenbank MySQL-Tutorial Leitfaden zur Optimierung der MySQL-Paging-Leistung

Leitfaden zur Optimierung der MySQL-Paging-Leistung

Feb 06, 2017 pm 03:43 PM

Viele Anwendungen neigen dazu, nur die neuesten oder beliebtesten Datensätze anzuzeigen. Damit jedoch weiterhin auf alte Datensätze zugegriffen werden kann, ist eine Seitennavigationsleiste erforderlich. Die Frage, wie man Paging über MySQL besser implementieren kann, war jedoch schon immer ein Problem. Obwohl es keine Standardlösung gibt, kann das Verständnis der zugrunde liegenden Schichten einer Datenbank dabei helfen, paginierte Abfragen zu optimieren.

Werfen wir einen Blick auf eine häufig verwendete Abfrage mit schlechter Leistung.

SELECT *
FROM city
ORDER BY id DESC
LIMIT 0, 15
Nach dem Login kopieren

Diese Abfrage dauert 0,00 Sekunden. Was ist also an dieser Abfrage falsch? Tatsächlich gibt es mit dieser Abfrageanweisung und diesen Parametern kein Problem, da sie den Primärschlüssel der folgenden Tabelle verwenden und nur 15 Datensätze lesen.

CREATE TABLE city (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  city varchar(128) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;
Nach dem Login kopieren

Das eigentliche Problem besteht darin, dass der Offset (Paging-Offset) groß ist, wie im Folgenden:

SELECT *
FROM city
ORDER BY id DESC
LIMIT 100000, 15;
Nach dem Login kopieren

Die obige Abfrage dauert 0,22 Sekunden, wenn 2 Millionen Datensatzzeilen vorhanden sind. Wenn Sie den SQL-Ausführungsplan über EXPLAIN anzeigen, können Sie feststellen, dass die SQL 100015 Zeilen abgerufen hat, aber am Ende nur 15 Zeilen benötigt wurden. Große Paging-Offsets erhöhen den Datenverbrauch und MySQL lädt viele Daten in den Speicher, die letztendlich nicht verwendet werden. Auch wenn wir davon ausgehen, dass die meisten Website-Benutzer nur auf die ersten Datenseiten zugreifen, kann eine kleine Anzahl von Anfragen mit großen Seitenversätzen Schaden für das gesamte System verursachen. Facebook ist sich dessen bewusst, aber anstatt die Datenbank zu optimieren, um mehr Anfragen pro Sekunde zu bearbeiten, konzentriert sich Facebook darauf, die Varianz der Antwortzeiten auf Anfragen zu reduzieren.

Für Paging-Anfragen gibt es noch eine weitere Information, die ebenfalls sehr wichtig ist, nämlich die Gesamtzahl der Datensätze. Mit der folgenden Abfrage können wir die Gesamtzahl der Datensätze leicht ermitteln.

SELECT COUNT(*)
FROM city;
Nach dem Login kopieren

Allerdings dauert das obige SQL 9,28 Sekunden, wenn InnoDB als Speicher-Engine verwendet wird. Eine falsche Optimierung besteht darin, SQL_CALC_FOUND_ROWS zu verwenden, um die Anzahl der Datensätze, die die Bedingungen erfüllen, im Voraus während der Paging-Abfrage vorzubereiten und dann einfach eine Auswahl von FOUND_ROWS() auszuführen. In den meisten Fällen bedeuten kürzere Abfrageanweisungen jedoch keine verbesserte Leistung. Leider wird diese Paging-Abfragemethode in vielen Mainstream-Frameworks verwendet. Schauen wir uns die Abfrageleistung dieser Anweisung an.

SELECT SQL_CALC_FOUND_ROWS *
FROM city
ORDER BY id DESC
LIMIT 100000, 15;
Nach dem Login kopieren

Diese Anweisung dauert 20,02 Sekunden, doppelt so lange wie die vorherige. Es stellt sich heraus, dass die Verwendung von SQL_CALC_FOUND_ROWS für Paging eine sehr schlechte Idee ist.

Sehen wir uns an, wie man optimiert. Der Artikel ist in zwei Teile unterteilt. Im ersten Teil geht es darum, wie man die Gesamtzahl der Datensätze erhält, und im zweiten Teil geht es darum, die tatsächlichen Datensätze zu erhalten.

Zählen Sie effizient die Anzahl der Zeilen

Wenn die verwendete Engine MyISAM ist, können Sie COUNT(*) direkt ausführen, um die Anzahl der Zeilen zu erhalten. Ebenso wird in einer Heap-Tabelle die Zeilennummer auch in den Metainformationen der Tabelle gespeichert. Wenn die Engine jedoch InnoDB ist, wird die Situation komplizierter, da InnoDB nicht die spezifische Anzahl von Zeilen in der Tabelle speichert.
Wir können die Anzahl der Zeilen zwischenspeichern und sie dann regelmäßig über einen Daemon-Prozess aktualisieren. Wenn einige Benutzervorgänge dazu führen, dass der Cache ungültig wird, führen Sie die folgende Anweisung aus:

SELECT COUNT(*)
FROM city
USE INDEX(PRIMARY);
Nach dem Login kopieren

Get the record

Geben Sie nun den wichtigsten Teil dieses Artikels ein, um die Datensätze in Paginierung anzuzeigen. Wie oben erwähnt, beeinträchtigen große Offsets die Leistung, daher müssen wir die Abfrageanweisung neu schreiben. Zur Demonstration erstellen wir eine neue Tabelle „News“, sortieren diese nach Aktualität (die neueste Veröffentlichung steht ganz oben) und implementieren ein leistungsstarkes Paging. Der Einfachheit halber gehen wir davon aus, dass die ID der neuesten Pressemitteilung auch die größte ist.

CREATE TABLE news(
   id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
   title VARCHAR(128) NOT NULL
) ENGINE=InnoDB;
Nach dem Login kopieren

Eine effizientere Methode basiert auf der letzten vom Benutzer angezeigten Nachrichten-ID. Die Anweisung zur Abfrage der nächsten Seite lautet wie folgt: Sie müssen die letzte auf der aktuellen Seite angezeigte ID übergeben.

SELECT *
FROM news WHERE id < $last_id
ORDER BY id DESC
LIMIT $perpage
Nach dem Login kopieren

Die Anweisung zum Abfragen der vorherigen Seite ist ähnlich, außer dass die erste ID der aktuellen Seite übergeben werden muss, und zwar in umgekehrter Reihenfolge.

SELECT *
FROM news WHERE id > $last_id
ORDER BY id ASC
LIMIT $perpage
Nach dem Login kopieren

Die obige Abfragemethode eignet sich für einfaches Paging, d. h. es wird keine spezifische Seitennavigation angezeigt, sondern nur „Vorherige Seite“ und „Nächste Seite“. Beispielsweise die Fußzeile eines Blogs Zeigt die Schaltflächen „Vorherige Seite“ und „Nächste Seite“ an. Wenn es jedoch immer noch schwierig ist, eine echte Seitennavigation zu erreichen, schauen wir uns einen anderen Weg an.

SELECT id
FROM (
   SELECT id, ((@cnt:= @cnt + 1) + $perpage - 1) % $perpage cnt
   FROM news 
   JOIN (SELECT @cnt:= 0)T
   WHERE id < $last_id
   ORDER BY id DESC
   LIMIT $perpage * $buttons
)C
WHERE cnt = 0;
Nach dem Login kopieren

通过上面的语句可以为每一个分页的按钮计算出一个offset对应的id。这种方法还有一个好处。假设,网站上正在发布一片新的文章,那么所有文章的位置都会往后移一位,所以如果用户在发布文章时换页,那么他会看见一篇文章两次。如果固定了每个按钮的offset Id,这个问题就迎刃而解了。Mark Callaghan发表过一篇类似的博客,利用了组合索引和两个位置变量,但是基本思想是一致的。

如果表中的记录很少被删除、修改,还可以将记录对应的页码存储到表中,并在该列上创建合适的索引。采用这种方式,当新增一个记录的时候,需要执行下面的查询重新生成对应的页号。

SET p:= 0;
UPDATE news SET page=CEIL((p:= p + 1) / $perpage) ORDER BY id DESC;
Nach dem Login kopieren

当然,也可以新增一个专用于分页的表,可以用个后台程序来维护。

UPDATE pagination T
JOIN (
   SELECT id, CEIL((p:= p + 1) / $perpage) page
   FROM news
   ORDER BY id
)C
ON C.id = T.id
SET T.page = C.page;
Nach dem Login kopieren

现在想获取任意一页的元素就很简单了:

SELECT *
FROM news A
JOIN pagination B ON A.id=B.ID
WHERE page=$offset;
Nach dem Login kopieren

还有另外一种与上种方法比较相似的方法来做分页,这种方式比较试用于数据集相对小,并且没有可用的索引的情况下—比如处理搜索结果时。在一个普通的服务器上执行下面的查询,当有2M条记录时,要耗费2sec左右。这种方式比较简单,创建一个用来存储所有Id的临时表即可(这也是最耗费性能的地方)。

CREATE TEMPORARY TABLE _tmp (KEY SORT(random))
SELECT id, FLOOR(RAND() * 0x8000000) random
FROM city;

ALTER TABLE _tmp ADD OFFSET INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, DROP INDEX SORT, ORDER BY random;
Nach dem Login kopieren

接下来就可以向下面一样执行分页查询了。

SELECT *
FROM _tmp
WHERE OFFSET >= $offset
ORDER BY OFFSET
LIMIT $perpage;
Nach dem Login kopieren

简单来说,对于分页的优化就是。。。避免数据量大时扫描过多的记录。

以上就是MySQL分页性能优化指南的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie man phpmyadmin öffnet Wie man phpmyadmin öffnet Apr 10, 2025 pm 10:51 PM

Sie können PhpMyAdmin in den folgenden Schritten öffnen: 1. Melden Sie sich beim Website -Bedienfeld an; 2. Finden und klicken Sie auf das Symbol phpmyadmin. 3. Geben Sie MySQL -Anmeldeinformationen ein; 4. Klicken Sie auf "Login".

MySQL: Eine Einführung in die beliebteste Datenbank der Welt MySQL: Eine Einführung in die beliebteste Datenbank der Welt Apr 12, 2025 am 12:18 AM

MySQL ist ein Open Source Relational Database Management -System, das hauptsächlich zum schnellen und zuverlässigen Speicher und Abrufen von Daten verwendet wird. Sein Arbeitsprinzip umfasst Kundenanfragen, Abfragebedingungen, Ausführung von Abfragen und Rückgabergebnissen. Beispiele für die Nutzung sind das Erstellen von Tabellen, das Einsetzen und Abfragen von Daten sowie erweiterte Funktionen wie Join -Operationen. Häufige Fehler umfassen SQL -Syntax, Datentypen und Berechtigungen sowie Optimierungsvorschläge umfassen die Verwendung von Indizes, optimierte Abfragen und die Partitionierung von Tabellen.

So verwenden Sie ein einzelnes Gewinde -Redis So verwenden Sie ein einzelnes Gewinde -Redis Apr 10, 2025 pm 07:12 PM

Redis verwendet eine einzelne Gewindearchitektur, um hohe Leistung, Einfachheit und Konsistenz zu bieten. Es wird E/A-Multiplexing, Ereignisschleifen, nicht blockierende E/A und gemeinsame Speicher verwendet, um die Parallelität zu verbessern, jedoch mit Einschränkungen von Gleichzeitbeschränkungen, einem einzelnen Ausfallpunkt und ungeeigneter Schreib-intensiver Workloads.

Mysqls Platz: Datenbanken und Programmierung Mysqls Platz: Datenbanken und Programmierung Apr 13, 2025 am 12:18 AM

Die Position von MySQL in Datenbanken und Programmierung ist sehr wichtig. Es handelt sich um ein Open -Source -Verwaltungssystem für relationale Datenbankverwaltung, das in verschiedenen Anwendungsszenarien häufig verwendet wird. 1) MySQL bietet effiziente Datenspeicher-, Organisations- und Abruffunktionen und unterstützt Systeme für Web-, Mobil- und Unternehmensebene. 2) Es verwendet eine Client-Server-Architektur, unterstützt mehrere Speichermotoren und Indexoptimierung. 3) Zu den grundlegenden Verwendungen gehören das Erstellen von Tabellen und das Einfügen von Daten, und erweiterte Verwendungen beinhalten Multi-Table-Verknüpfungen und komplexe Abfragen. 4) Häufig gestellte Fragen wie SQL -Syntaxfehler und Leistungsprobleme können durch den Befehl erklären und langsam abfragen. 5) Die Leistungsoptimierungsmethoden umfassen die rationale Verwendung von Indizes, eine optimierte Abfrage und die Verwendung von Caches. Zu den Best Practices gehört die Verwendung von Transaktionen und vorbereiteten Staten

Warum MySQL verwenden? Vorteile und Vorteile Warum MySQL verwenden? Vorteile und Vorteile Apr 12, 2025 am 12:17 AM

MySQL wird für seine Leistung, Zuverlässigkeit, Benutzerfreundlichkeit und Unterstützung der Gemeinschaft ausgewählt. 1.MYSQL bietet effiziente Datenspeicher- und Abruffunktionen, die mehrere Datentypen und erweiterte Abfragevorgänge unterstützen. 2. Übernehmen Sie die Architektur der Client-Server und mehrere Speichermotoren, um die Transaktion und die Abfrageoptimierung zu unterstützen. 3. Einfach zu bedienend unterstützt eine Vielzahl von Betriebssystemen und Programmiersprachen. V.

So stellen Sie eine Verbindung zur Datenbank von Apache her So stellen Sie eine Verbindung zur Datenbank von Apache her Apr 13, 2025 pm 01:03 PM

Apache verbindet eine Verbindung zu einer Datenbank erfordert die folgenden Schritte: Installieren Sie den Datenbanktreiber. Konfigurieren Sie die Datei web.xml, um einen Verbindungspool zu erstellen. Erstellen Sie eine JDBC -Datenquelle und geben Sie die Verbindungseinstellungen an. Verwenden Sie die JDBC -API, um über den Java -Code auf die Datenbank zuzugreifen, einschließlich Verbindungen, Erstellen von Anweisungen, Bindungsparametern, Ausführung von Abfragen oder Aktualisierungen und Verarbeitungsergebnissen.

So sehen Sie sich den SQL -Datenbankfehler an So sehen Sie sich den SQL -Datenbankfehler an Apr 10, 2025 pm 12:09 PM

Die Methoden zum Anzeigen von SQL -Datenbankfehlern sind: 1. Fehlermeldungen direkt anzeigen; 2. Verwenden Sie Showfehler und Warnungsbefehle anzeigen; 3.. Greifen Sie auf das Fehlerprotokoll zu. 4. Verwenden Sie Fehlercodes, um die Ursache des Fehlers zu finden. 5. Überprüfen Sie die Datenbankverbindung und die Abfrage -Syntax. 6. Verwenden Sie Debugging -Tools.

Überwachen Sie Redis Tröpfchen mit Redis Exporteur Service Überwachen Sie Redis Tröpfchen mit Redis Exporteur Service Apr 10, 2025 pm 01:36 PM

Eine effektive Überwachung von Redis -Datenbanken ist entscheidend für die Aufrechterhaltung einer optimalen Leistung, die Identifizierung potenzieller Engpässe und die Gewährleistung der Zuverlässigkeit des Gesamtsystems. Redis Exporteur Service ist ein leistungsstarkes Dienstprogramm zur Überwachung von Redis -Datenbanken mithilfe von Prometheus. In diesem Tutorial führt Sie die vollständige Setup und Konfiguration des Redis -Exporteur -Dienstes, um sicherzustellen, dass Sie nahtlos Überwachungslösungen erstellen. Durch das Studium dieses Tutorials erhalten Sie voll funktionsfähige Überwachungseinstellungen

See all articles