Frage

  1. Ich habe eine Tabelle, die jetzt über 43 Millionen Datensätze enthält. Ausführen SELECT, Normalerweise wähle ich Datensätze mit demselben Feld aus, sagen wir A. Wird es effizienter sein, die Tabelle durch verschiedene Tische in mehrere Tabellen zu unterteilen? A und in der Datenbank speichern? Wie viel kann ich gewinnen?

  2. Ich habe einen Tisch mit dem Namen entry: {entryid (PK), B}, enthält 6.000 Datensätze und mehrere andere Tabellen mit der ähnlichen Struktur T1: {id(PK), entryid, C, ...}, über Millionen von Aufzeichnungen. Haben die folgenden zwei Prozesse die gleiche Effizienz?

    SELECT id FROM T1, entry WHERE T1.entryid = entry.entryid AND entry.B = XXX

und

SELECT entryid FROM entry WHERE B = XXX
//format a string S as (entryid1, entryid2, ... )
//then run
SELECT id FROM T1 WHERE entryid IN S
War es hilfreich?

Lösung

In diesem Fall werde ich zuerst Ihre zweite Frage beantworten.

Es gibt eine Möglichkeit, die Fragen zu mischen, um sich als eine zu verhalten und es effizient zu tun.

Ihre erste Methode ist eine Abfrage, die sich wie folgt verhält

  • Beitritt von T1 und entry durch entryid Bildung einer riesigen Temperaturtabelle
  • Überqueren Sie die Temperaturtabelle, um die WHERE -Klausel zu verarbeiten

Ihre zweite Methode sind im Wesentlichen zwei Abfragen

  • Sieh nach oben entryid wobei B ein Wert xxx ist
  • Alles kompilieren entryid Werte in einer Zeichenfolge
  • Ausführen von Abfragen mithilfe WHERE entryid IN
  • Die übereinstimmende Liste in einer nicht indizierten Temperaturtabelle
  • Kartesianische Beitritt zurück zu T1, um zu sehen, welche Werte übereinstimmen

In beiden Fällen müssen Sie immer noch eine Temperaturtabelle von bilden entryid Werte

Sie müssen die Ausführung der Abfrage neu organisieren, auch bekannt als Refactoring.

Hier ist Ihre erste Abfrage, die total neu gestaltet ist:

SELECT
    A.entryid
FROM
    (SELECT entryid id FROM entry WHERE B = XXX) A
    LEFT JOIN T1 USING (id)
;

Dies präsentiert Ihre Frage, aber es macht zwei Dinge

  1. Es stellt zuerst in der Liste der Einträge mit der Where -Klausel zusammen
  2. Es führt den Join basierend auf der Länge der Unterabfrage a durch

Diese Umstrukturierung sollte die Verarbeitung ohne zusätzliche Tabellenänderungen beschleunigen.

Seit der Unterabfrage A wird jedoch erhältlich entryid Werte basierend auf dem Wert von B, Sie sollten einen Index haben, der diese schnell zusammenrunden. Bitte erstellen Sie diesen Index:

ALTER TABLE entry ADD INDEX B_entryid_ndx (B,entryid);

Mit dieser neuen neu refaktorierten Abfrage und der Erstellung dieses zusätzlichen Index ist es so schnell wie möglich, da die Refactoring -Kräfte, wo sie vor dem Zusammenfügen stattfinden können, umgestaltet werden.

In Bezug auf Ihre erste Frage sollte die refaktorierte Abfrage genau das abrufen, was sie braucht, unabhängig davon, ob sie nicht aufgeteilt ist. Die Partitionierung wäre nur eine Auswahl der Speichermotorauswahl.

MySQL unterstützt zwei Paradigmen für die Partitionierung

Mit der Merge -Speicher -Engine gibt es keinen langen Migrationspfad. Die Zuordnung findet in 2 Sekunden statt. Die Wartung jeder einzelnen Tabelle kann eine Abfrage gegen die Merge -Engine beeinflussen, wenn es keinen Primärschlüssel gibt, um ein MyISAM -Tisch aus einer anderen MyISAM -Tabelle einzigartig zu identifizieren.

Mit der Tabellenpartition verfügt die einzelnen Tabellen mit einer Partitionskarte ein. Die Mapping kann einen Migrationspfad enthalten. Die Wartung ist nur eine gemischte Tasche wie bei jedem anderen Tisch.

In beiden Fällen muss ein gut gestaltetes Indexierungsschema vorhanden sein. Wieso den? Die Abfrage ist wo, bestellen von und gruppen nach Klauseln sollte bestimmen, welche Indizes wirklich benötigt werden, um die Abfrage zu unterstützen.

Andere Tipps

Ich würde über die Verwendung von Tabellenpartitionierung nachdenken. Sie erwähnen keine MySQL -Version oder Speicher -Engine -Typen. Hier ist der DOC -Link:

http://dev.mysql.com/doc/refman/5.6/en/partitioning.html

für 5.6

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top