Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
SQLKonstrukte für parallel Abfragen in Aurora My SQL
Im folgenden Abschnitt finden Sie weitere Informationen darüber, warum bestimmte SQL Anweisungen parallel Abfragen verwenden oder nicht. In diesem Abschnitt wird auch beschrieben, wie die SQL Funktionen von Aurora My mit parallel Abfragen interagieren. Mit Hilfe dieser Informationen können Sie Leistungsprobleme in Clustern diagnostizieren, die Parallel Query verwenden. Außerdem können Sie nachvollziehen, wie Parallel Query auf Ihren spezifischen Workload angewendet wird.
Die Entscheidung für Parallel Query hängt von vielen Faktoren ab, die zu dem Zeitpunkt wirken, an dem die Anweisung ausgeführt wird. Es kann also sein, dass Parallel Query für bestimmte Abfragen immer, nie oder nur unter bestimmten Bedingungen zum Einsatz kommt.
Tipp
Wenn Sie sich diese Beispiele unter ansehenHTML, können Sie das Widget „Kopieren“ in der oberen rechten Ecke jeder Codeliste verwenden, um den SQL Code zu kopieren und es selbst auszuprobieren. Durch die Verwendung des Widgets Copy (Kopieren) wird ein Kopieren der zusätzlichen Zeichen um die Aufforderung mysql>
und die Fortsetzungszeilen ->
vermieden.
Themen
- EXPLAINAussage
- WHERE-Klausel
- Sprache der Datendefinition (DDL)
- Spaltendatentypen
- Partitionierte Tabellen
- Aggregatfunktionen, GROUP BY-Klauseln und HAVING Klauseln
- Funktionsaufrufe in der WHERE Klausel
- LIMIT-Klausel
- Vergleichsoperatoren
- Joins
- Unterabfragen
- UNION
- Ansichten
- Anweisungen in der Datenmanipulationssprache () DML
- Transaktionen und Sperren
- B-Baum-Indizes
- Indizes für die Volltextsuche (FTS)
- Virtuelle Spalten
- Integrierte Caching-Mechanismen
- Optimierungshinweise
- Meine ISAM temporären Tabellen
EXPLAINAussage
Wie aus den Beispielen aus diesem Abschnitt hervorgeht, gibt die EXPLAIN
-Anweisung an, ob die jeweilige Stufe einer Abfrage derzeit parallelabfragetauglich ist. Darüber hinaus gibt sie auch an, welche Aspekte einer Abfrage auf die nächste Speicherschicht herabgestuft werden können. Die wichtigsten Bestandteile im Abfrageplan sind folgende:
-
Wenn in der
NULL
-Spalte ein anderer Wert alskey
steht, liegt nahe, dass die Abfrage mit Index-Lookups effizient möglich ist. Der Einsatz von Parallel Query ist unwahrscheinlich. -
Wenn in der Spalte
rows
ein kleiner Wert steht (d. h. nicht im Millionenbereich), kann dies bedeuten, dass für die Abfrage zu wenig Daten verfügbar sind, als dass sich eine Parallelabfrage lohnen würde. Das bedeutet, dass eine parallele Abfrage unwahrscheinlich ist. -
Die Spalte
Extra
zeigt an, ob mit einer Parallelabfrage zu rechnen ist. Die Ausgabe kann in etwa wie im folgenden Beispiel aussehen.Using parallel query (
A
columns,B
filters,C
exprs;D
extra)Die Zahl vor
columns
gibt an, wie viele Spalten im Abfrageblock hinterlegt sind.Die Zahl vor
filters
gibt an, wie vieleWHERE
-Prädikate einen einfachen Vergleich zwischen Spaltenwert und einer Konstante darstellen. Es können Größen wie „Gleichheit“ und „Ungleichheit“, aber auch Bereiche verglichen werden. Aurora parallelisiert diese Prädikattypen am effektivsten.Die Zahl vor
exprs
gibt die Anzahl der Ausdrücke (z. B. Funktionsaufrufe, Operatoren oder sonstige Ausdrücke) an, die auch parallelisiert werden können – wenn auch nicht so effektiv wie eine Filterbedingung.Die Zahl vor
extra
gibt an, wie viele Ausdrücke nicht herabgestuft werden können und deshalb vom Hauptknoten ausgeführt werden.
Betrachten Sie dazu die folgende EXPLAIN
-Ausgabe.
mysql>
explain select p_name, p_mfgr from part->
where p_brand is not null->
and upper(p_type) is not null->
and round(p_retailprice) is not null;+----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+
Aus der Extra
-Spalte geht hervor, dass aus jeder Zeile fünf Spalten extrahiert werden, mit denen die Abfragebedingungen bewertet und der Ergebnissatz konstruiert werden. Ein WHERE
-Prädikat beinhaltet einen Filter – in diesem Fall eine Spalte, die direkt in der WHERE
-Klausel getestet wird. Kommen zwei WHERE
-Klauseln vor, müssen kompliziertere Ausdrücke bewertet werden (die in diesem Fall Funktionsaufrufe beinhalten). Das Feld 0 extra
bestätigt, dass alle Operationen in der WHERE
-Klausel im Zuge der Parallelabfrageverarbeitung in die Speicherschicht herabgestuft werden.
Wird Parallel Query nicht ausgewählt, lässt sich der Grund dafür meist aus den anderen Spalten der EXPLAIN
-Ausgabe ableiten. So kann möglicherweise sein, dass der rows
-Wert zu klein ist oder dass die Spalte possible_keys
angibt, dass die Abfrage statt auf einen datenintensiven Scan auf einen Index-Lookup zurückgreift. Das folgende Beispiel zeigt eine Abfrage, bei der der Optimierer schätzen kann, dass die Abfrage nur eine kleine Anzahl von Zeilen durchsucht. Dies erfolgt auf der Basis der Eigenschaften des Primärschlüssels. Eine Parallelabfrage ist deshalb nicht erforderlich.
mysql>
explain select count(*) from part where p_partkey between 1 and 100;+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | 1 | SIMPLE | part | range | PRIMARY | PRIMARY | 4 | NULL | 99 | Using where; Using index | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
Die Ausgabe mit Auskunft zur Verwendung von Parallel Query berücksichtigt alle Faktoren, die zu dem Zeitpunkt verfügbar waren, als die EXPLAIN
-Anweisung ausgeführt wurde. Möglicherweise trifft der Optimierer zum Zeitpunkt der tatsächlichen Abfrageausführung eine andere Auswahl, wenn bis dahin eine andere Ausgangslage herrscht. EXPLAIN
könnte beispielsweise melden, dass eine Anweisung Parallel Query verwendet. Wird die Abfrage später dann tatsächlich ausgeführt, könnte sein, dass Parallel Query aufgrund der dann vorliegenden Bedingungen nicht nötig ist. Zu solchen Bedingungen können mehrere weitere parallele Abfragen gehören, die gleichzeitig ausgeführt werden. Es kann sich auch um Zeilen handeln, die aus der Tabelle gelöscht werden, um einen neuen Index, der erstellt wird, um zu viel Zeit, die in einer offenen Transaktion verstreicht, usw.
WHERE-Klausel
Damit die parallele Abfrageausführung genutzt werden kann, muss die Abfrage eine WHERE
-Klausel enthalten.
Die parallele Abfrageausführung beschleunigt viele unterschiedliche Ausdrücke, die in der WHERE
-Klausel vorkommen:
-
Einfache Abgleiche zwischen einem Spaltenwert und einer Konstante (Filter). Bei diesen Abgleichen lohnt sich die Herabstufung auf die Speicherschicht am meisten. Wie viele Filterausdrücke in einer Abfrage vorkommen, ist in der
EXPLAIN
-Ausgabe zusammengefasst. -
Wo dies möglich ist, werden auch andere Ausdrücke aus der
WHERE
-Klausel in die Speicherschicht hinabgestuft. Wie viele solche Ausdrücke in einer Abfrage vorkommen, ist in derEXPLAIN
-Ausgabe zusammengefasst. Bei diesen Ausdrücken kann es sich um Funktionsaufrufe,LIKE
-Operatoren,CASE
-Ausdrücke und Ähnliches handeln. -
Bestimmte Funktionen und Operatoren werden von Parallel Query derzeit noch nicht herabgestuft. Wie viele solche Ausdrücke in einer Abfrage vorkommen, wird mit dem
extra
-Zähler in derEXPLAIN
-Ausgabe angegeben. Der Rest der Abfrage verwendet Parallel Query. -
Ausdrücke aus der Auswahlliste werden nicht herabgestuft. Für Abfragen mit solchen Funktionen kann es sich aber positiv auswirken, dass die Zwischenergebnisse von Parallelabfragen weniger Netzwerkdatenverkehr verursachen. So können beispielsweise Abfragen, die Aggregationsfunktionen aus der Auswahlliste aufrufen, von Parallelabfragen profitieren, selbst wenn die Aggregationsfunktionen selbst nicht herabgestuft werden.
Die nachfolgend abgebildete Abfrage scannt beispielsweise die gesamte Tabelle und verarbeitet alle Werte aus der P_BRAND
-Spalte. Es handelt sich dabei allerdings nicht um eine Parallelabfrage, weil sie keine WHERE
-Klausel enthält.
mysql>
explain select count(*), p_brand from part group by p_brand;+----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | 1 | SIMPLE | part | ALL | NULL | NULL | NULL | NULL | 20427936 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+
Die nächste Abfrage enthält hingegen WHERE
-Prädikate, die die Ergebnisse filtern. Deshalb ist eine Parallelabfrage möglich:
mysql>
explain select count(*), p_brand from part where p_name is not null->
and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000->
group by p_brand;+----+...+----------+-------------------------------------------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using temporary; Using filesort; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+...+----------+-------------------------------------------------------------------------------------------------------------+
Wenn der Optimierer davon ausgeht, dass zu einem Abfrageblock nur wenige Zeilen zurückgegeben werden, wird Parallel Query für diesen Abfrageblock nicht verwendet. Im nachfolgenden Beispiel wird ein Größer-als-Operator in der Primärschlüssel-Spalte auf mehrere Millionen Zeilen angewendet. Das sorgt dafür, dass Parallel Query verwendet wird. Dagegen wird davon ausgegangen, dass die Kleiner-als-Gegenprobe nur auf wenige Zeilen anwendbar ist. Parallel Query kommt nicht zum Einsatz.
mysql>
explain select count(*) from part where p_partkey > 10;+----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
mysql>
explain select count(*) from part where p_partkey < 10;+----+...+------+--------------------------+ | id |...| rows | Extra | +----+...+------+--------------------------+ | 1 |...| 9 | Using where; Using index | +----+...+------+--------------------------+
Sprache der Datendefinition (DDL)
In Aurora My SQL Version 2 ist die parallel Abfrage nur für Tabellen verfügbar, für die keine Fast Data Definition Language (DDL) -Operationen ausstehen. In Aurora My SQL Version 3 können Sie die parallel Abfrage für eine Tabelle gleichzeitig mit einer DDL Sofortoperation verwenden.
Instant DDL in Aurora My SQL Version 3 ersetzt die DDL Schnellfunktion in Aurora My SQL Version 2. Informationen zu Instant finden DDL Sie unterSofortige DDL (Aurora MySQL Version 3).
Spaltendatentypen
In Aurora My SQL Version 3 kann die parallel Abfrage mit Tabellen funktionieren, die Spalten mit den DatentypenTEXT
, BLOB
JSON
, und enthaltenGEOMETRY
. Es kann auch mit VARCHAR
- und CHAR
-Spalten mit einer maximalen deklarierten Länge von mehr als 768 Byte arbeiten. Wenn sich Ihre Abfrage auf Spalten bezieht, die so große Objekttypen enthalten, erhöht die zusätzliche Arbeit zum Abrufen der Abfrageverarbeitung einen gewissen Aufwand. Überprüfen Sie in diesem Fall, ob die Abfrage die Verweise auf diese Spalten weglassen kann. Wenn dies nicht der Fall ist, führen Sie Benchmarks aus, um zu bestätigen, ob solche Abfragen schneller sind, wenn die parallele Abfrage aktiviert oder deaktiviert ist.
In Aurora My SQL Version 2 gelten für parallel Abfragen die folgenden Einschränkungen für große Objekttypen:
-
Die Datentypen
TEXT
,BLOB
,JSON
undGEOMETRY
werden von parallelen Abfragen nicht unterstützt. Eine Abfrage, die sich auf Spalten dieses Typs bezieht, kann keine parallelen Abfragen nutzen. -
Spalten unterschiedlicher Länge (Datentypen
VARCHAR
undCHAR
) sind bis zur deklarierten Länge (max. 768 Byte) mit Parallel Query kompatibel. Eine Abfrage, die sich auf Spalten der Typen bezieht, die mit mehr Höchstlänge deklariert sind, kann Parallel Query nicht nutzen. In Spalten, in denen Zeichensätze mit mehreren Byte Länge vorkommen, ist im Byte-Höchstwert die maximale Byte-Anzahl des Zeichensatzes berücksichtigt. Für eineutf8mb4
-Spalte mit dem ZeichensatzVARCHAR(192)
(maximal 4 Byte Zeichenlänge) kann beispielsweise eine Parallelabfrage gestartet werden, nicht jedoch für eineVARCHAR(193)
-Spalte.
Partitionierte Tabellen
In Aurora My SQL Version 3 können Sie partitionierte Tabellen mit parallel Abfrage verwenden. Da partitionierte Tabellen intern als mehrere kleinere Tabellen dargestellt werden, verwendet eine Abfrage, die eine parallele Abfrage für eine nicht partitionierte Tabelle verwendet, möglicherweise keine parallele Abfrage für eine identische partitionierte Tabelle. Aurora My SQL prüft, ob jede Partition groß genug ist, um sich für die parallel Abfrageoptimierung zu qualifizieren, anstatt die Größe der gesamten Tabelle zu bewerten. Prüfen Sie, ob die Statusvariable Aurora_pq_request_not_chosen_small_table
inkrementiert wird, wenn eine Abfrage in einer partitionierten Tabelle die parallele Abfrage nicht wie erwartet verwendet.
Betrachten Sie beispielsweise eine Tabelle, die mit PARTITION BY HASH (
partitioniert ist, und eine andere Tabelle, die mit column
) PARTITIONS 2PARTITION BY HASH (
partitioniert ist. In der Tabelle mit zwei Partititionen sind die Partitionen fünfmal so groß wie die Tabelle mit zehn Partitionen. Daher wird eine parallele Abfrage eher für Abfragen gegen die Tabelle mit weniger Partitionen verwendet. Im folgenden Beispiel hat die Tabelle column
) PARTITIONS 10PART_BIG_PARTITIONS
zwei Partitionen und PART_SMALL_PARTITIONS
hat zehn Partitionen. Bei identischen Daten wird eine parallele Abfrage eher für die Tabelle mit weniger großen Partitionen verwendet.
mysql> explain select count(*), p_brand from part_big_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | 1 | SIMPLE | part_big_partitions | p0,p1 | Using where; Using temporary; Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra; 1 group-bys, 1 aggrs) | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ mysql> explain select count(*), p_brand from part_small_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+-----------------------+-------------------------------+------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+-----------------------+-------------------------------+------------------------------+ | 1 | SIMPLE | part_small_partitions | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | Using where; Using temporary | +----+-------------+-----------------------+-------------------------------+------------------------------+
Aggregatfunktionen, GROUP BY-Klauseln und HAVING Klauseln
In Abfragen mit Aggregationsfunktionen werden große Tabellen mit sehr vielen Zeilen gescannt. Sie eignen sich deshalb oft besonders gut für Parallelabfragen.
In Aurora My SQL 3 kann die parallel Abfrage aggregierte Funktionsaufrufen in der Auswahlliste und der HAVING
Klausel optimieren.
Vor Aurora My SQL 3 wurden Aggregatfunktionsaufrufen in der Auswahlliste oder der HAVING
Klausel nicht auf die Speicherebene übertragen. Eine parallele Abfrage kann dennoch die Leistung solcher Abfragen mit Aggregationsfunktionen verbessern – indem sie zuerst auf der Speicherschicht Spaltenwerte aus den Rohdatenseiten parallel extrahiert. Anschließend überträgt Parallel Query diese Werte in einem kompakten Tupelformat an den Hauptknoten zurück und nicht als vollständige Datenseiten. Wie immer muss die Abfrage mindestens 1 WHERE
-Prädikat enthalten, das für Parallel Query aktiviert ist.
Die nachfolgenden einfach gehaltenen Beispiele veranschaulichen, welche aggregierte Abfragen von Parallel Query profitieren. Dies gilt zum einen durch Rückgabe unmittelbarer, kompakt gehaltener Ergebnisse an den Hauptknoten und eventuell zusätzlich durch Herausfilterung nicht passender Zeilen aus den Zwischenergebnissen.
mysql>
explain select sql_no_cache count(distinct p_brand) from part where p_mfgr = 'Manufacturer#5';+----+...+----------------------------------------------------------------------------+ | id |...| Extra | +----+...+----------------------------------------------------------------------------+ | 1 |...| Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------------------------------------------------------------------------+
mysql>
explain select sql_no_cache p_mfgr from part where p_retailprice > 1000 group by p_mfgr having count(*) > 100;+----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (3 columns, 0 filters, 1 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+
Funktionsaufrufe in der WHERE Klausel
Aurora kann die Optimierung der parallelen Abfrageausführung auf Aufrufe der meisten integrierten Funktionen der WHERE
-Klausel anwenden. Durch die Parallelisierung dieser Funktionsaufrufen wird dem Hauptknoten ein Teil der CPU Arbeit entzogen. Die parallel ablaufende Bewertung der Prädikatfunktionen in der ersten Abfragephase ermöglicht es Aurora, die Datenmenge zu minimieren, die im späteren Verlauf übertragen und verarbeitet werden muss.
Aktuell werden nicht alle Funktionsaufrufe aus der Auswahlliste parallelisiert. Diese Funktionen werden vom Hauptknoten auch dann bewertet, wenn in der WHERE
-Klausel dieselben Funktionsaufrufe enthalten sind. Die ursprünglichen Werte aus betroffenen Spalten werden in die Tupel aufgenommen, die vom Speicherknoten zum Hauptknoten zurückübertragen werden. Der Hauptknoten führt alle Transformationen aus, z. B. UPPER
, CONCATENATE
usw., und generiert die endgültigen Werte für den Abfragesatz.
Im folgenden Beispiel parallelisiert Parallel Query den Aufruf von LOWER
, da diese Funktion in der WHERE
-Klausel enthalten ist. Parallel Query wirkt sich nicht auf die Aufrufe von SUBSTR
und UPPER
aus, da sie in der Auswahlliste stehen.
mysql>
explain select sql_no_cache distinct substr(upper(p_name),1,5) from part->
where lower(p_name) like '%cornflower%' or lower(p_name) like '%goldenrod%';+----+...+---------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+---------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+...+---------------------------------------------------------------------------------------------+
Die gleichen Überlegungen gelten für andere Ausdrücke wie CASE
-Ausdrücke oder LIKE
-Operatoren. Im der folgenden Beispiel ist beispielsweise zu sehen, dass die parallele Abfrage in der CASE
-Klausel den LIKE
-Ausdruck und die WHERE
-Operatoren evaluiert.
mysql>
explain select p_mfgr, p_retailprice from part->
where p_retailprice > case p_mfgr->
when 'Manufacturer#1' then 1000->
when 'Manufacturer#2' then 1200->
else 950->
end->
and p_name like '%vanilla%'->
group by p_retailprice;+----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (4 columns, 0 filters, 2 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+
LIMIT-Klausel
Derzeit können Abfrageblöcke mit LIMIT
-Klausel nicht parallel abgefragt werden. Parallel Query könnte jedoch für frühere Abfragephasen mit GROUP
BY, ORDER BY
oder Join-Abfragen geeignet sein.
Vergleichsoperatoren
Der Optimierer schätzt ab, wie viele Zeilen gescannt werden müssen, um die Vergleichsoperatoren bewerten zu können, und entscheidet ausgehend von dieser Schätzung, ob Parallel Query verwendet wird.
Das erste Beispiel belegt, dass ein Gleichheitsvergleich gegen die Hauptschlüsselspalte effizient ohne Parallel Query möglich ist. Das zweite Beispiel belegt, dass für einen ähnlichen Vergleich gegen eine nicht indizierte Spalte mehrere Millionen Zeilen gescannt werden müssen. Parallel Query lohnt sich deshalb.
mysql>
explain select * from part where p_partkey = 10;+----+...+------+-------+ | id |...| rows | Extra | +----+...+------+-------+ | 1 |...| 1 | NULL | +----+...+------+-------+
mysql>
explain select * from part where p_type = 'LARGE BRUSHED BRASS';+----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
Die gleichen Kriterien gelten für "ist ungleich"-Prüfungen und Bereichsvergleiche (z. B. kleiner als, größer als, ist gleich oder BETWEEN
. Der Optimierer schätzt ab, wie viele Zeilen zu scannen sind, und entscheidet dann, ob sich eine parallele Abfrage angesichts des E/A-Gesamt-Volumens lohnt.
Joins
Join-Abfragen mit großen Tabellen sind in der Regel datenintensive Operationen, die von der Optimierung der parallelen Abfrageausführung profitieren. Derzeit werden Vergleiche von Spaltenwerten aus mehreren Tabellen (also die Join-Prädikate) nicht parallelisiert. Parallel Query kann allerdings einen Teil der internen Verarbeitung aus anderen Join-Phasen herunterstufen – z. B. die Erstellung des Bloom-Filters während eines Hash-Join. Parallel Query kann auch ohne WHERE
-Klausel auf Join-Abfragen angewendet werden. Join-Abfragen sind in dieser Hinsicht Ausnahmen von der Regel, dass Parallelabfragen ohne WHERE
-Klausel nicht möglich sind.
Jede Phase der Join-Verarbeitung wird ausgewertet, um festzustellen, ob sie für eine Parallelabfrage in Frage kommt. Falls mehrere Phasen parallelabfragetauglich sind, werden sie nacheinander ausgeführt. Was die Obergrenze für gleichzeitige Abfragen angeht, bedeutet dies, dass jede Join-Abfrage als separate Parallelabfragesitzung zählt.
Wenn eine Join-Abfrage beispielsweise mit WHERE
-Prädikaten die Zeilen einer verknüpften Tabelle filtert, kann diese Filteroption Parallel Query verwenden. Ein weiteres Beispiel ist die Verknüpfung einer großen mit einer kleinen Tabelle mittels Hash-Join in einer Join-Abfrage. In diesem Fall kann der Tabellenscan für die Generierung der Datenstruktur des Bloom-Filters Parallel Query möglicherweise verwenden.
Anmerkung
Parallele Abfragen werden typischerweise für ressourcenintensive Abfragen verwendet, die von der Hash-Join-Optimierung profitieren. Die Methode zum Aktivieren der Hash-Join-Optimierung hängt von der Aurora SQL My-Version ab. Einzelheiten zu den einzelnen Versionen finden Sie unter Hash-Join für parallele Abfrage-Cluster aktivieren. Informationen zur effektiven Verwendung von Hash-Joins finden Sie unter Optimierung großer Aurora My SQL Join-Abfragen mit Hash-Joins.
mysql>
explain select count(*) from orders join customer where o_custkey = c_custkey;+----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | id |...| table | type | possible_keys | key |...| rows | Extra | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | 1 |...| customer | index | PRIMARY | c_nationkey |...| 15051972 | Using index | | 1 |...| orders | ALL | o_custkey | NULL |...| 154545408 | Using join buffer (Hash Join Outer table orders); Using parallel query (1 columns, 0 filters, 1 exprs; 0 extra) | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+
In Join-Abfragen, die mit geschachtelten Schleifen arbeiten, könnte der äußerste geschachtelte Schleifenblock parallele Abfragen verwenden. Die Anwendung von parallelen Abfragen hängt von den gleichen Faktoren wie immer ab, z. B. dem Vorhandensein zusätzlicher Filterbedingungen in der WHERE
-Klausel.
mysql>
-- Nested loop join with extra filter conditions can use parallel query.mysql>
explain select count(*) from part, partsupp where p_partkey != ps_partkey and p_name is not null and ps_availqty > 0;+----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | | 1 | SIMPLE | partsupp |...| 78164450 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+
Unterabfragen
Der äußere Abfrageblock und der innere Unterabfrageblock können jeweils parallele Abfragen verwenden oder nicht. Ob sie dies tun, ist für jeden Block von den gewöhnlichen Eigenschaften der Tabelle, der WHERE
-Klausel usw. abhängig. In der folgenden Abfrage kommt Parallel Query am Unterabfrageblock zum Einsatz, nicht jedoch am Außenblock.
mysql>
explain select count(*) from part where-->
p_partkey < (select max(p_partkey) from part where p_name like '%vanilla%');+----+-------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| NULL | Impossible WHERE noticed after reading const tables | | 2 | SUBQUERY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+-------------+...+----------+----------------------------------------------------------------------------+
Für korrelierte Unterabfragen steht die Optimierung der parallelen Abfrageausführung nicht zur Verfügung.
UNION
Jeder Abfrageblock einer UNION
-Abfrage kann Parallel Query nutzen (oder nicht). Ausschlaggebend sind die Tabelleneigenschaften und die WHERE
-Klausel usw. des jeweiligen UNION
-Teils.
mysql>
explain select p_partkey from part where p_name like '%choco_ate%'->
union select p_partkey from part where p_name like '%vanil_a%';+----+----------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+----------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | 2 | UNION |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | NULL | UNION RESULT | <union1,2> |...| NULL | Using temporary | +----+--------------+...+----------+----------------------------------------------------------------------------+
Anmerkung
Die UNION
-Klauseln in der Abfrage werden nacheinander ausgeführt. Selbst wenn die Abfrage mehrstufig ist und in jeder Phase Parallel Query zum Einsatz kommt, führt sie Parallel Query jedes Mal separat aus. Deshalb gilt mit Hinblick auf die Höchstzahl gleichzeitig zulässiger Parallelabfragen auch eine komplexe mehrstufige Abfrage nur als 1 Abfrage.
Ansichten
Der Optimierer verwendet beim Umschreiben jeder Abfrage eine Ansicht als längere Abfrage. Dazu werden die zugrunde liegenden Tabellen verwendet. Das bedeutet, dass die Funktionsweise von Parallel Query unabhängig von der Tabellenreferenz (Ansicht oder tatsächliche Tabelle) gleich ist. Für die fertige umgeschriebene Abfrage gelten die gleichen Kriterien hinsichtlich der Verwendung von Parallel Query für eine Abfrage und hinsichtlich der Herabstufung einzelner Teile.
Beispielsweise zeigt der folgende Abfrageplan eine Ansichtsdefinition, die Parallel Query in der Regel nicht verwendet. Wenn die Ansicht mit zusätzlichen WHERE
Klauseln abgefragt wird, SQL verwendet Aurora My eine parallel Abfrage.
mysql>
create view part_view as select * from part;mysql>
explain select count(*) from part_view where p_partkey is not null;+----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 0 filters, 0 exprs; 1 extra) | +----+...+----------+----------------------------------------------------------------------------+
Anweisungen in der Datenmanipulationssprache () DML
Die INSERT
-Anweisung kann Parallel Query für die SELECT
-Verarbeitungsphase verwenden, wenn der SELECT
-Teil die sonstigen Bedingungen für eine Parallelabfrage erfüllt.
mysql>
create table part_subset like part;mysql>
explain insert into part_subset select * from part where p_mfgr = 'Manufacturer#1';+----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
Anmerkung
In der Regel liegen die Daten zu den neu eingefügten Zeilen nach der INSERT
-Anweisung im Bufferpool. Deshalb kann sein, dass eine Tabelle unmittelbar nach dem Einfügen vieler Zeilen nicht für Parallel Query in Frage kommt. Erst wenn die Daten im normalen Betrieb aus dem Bufferpool entfernt wurden, können in Abfragen gegen die Tabelle wieder Parallelabfragen zum Einsatz kommen.
Die CREATE TABLE AS SELECT
-Anweisung greift nicht auf Parallel Query zurück – auch dann nicht, wenn der SELECT
-Teil der Anweisung ansonsten parallelabfragefähig ist. Der DDL Aspekt dieser Anweisung macht sie mit der parallel Abfrageverarbeitung nicht kompatibel. Dagegen kann der INSERT ... SELECT
-Teil der SELECT
-Anweisung Parallel Query verwenden.
Parallel Query wird nie verwendet, wenn DELETE
- oder UPDATE
-Anweisungen vorliegen. Dies gilt unabhängig von der Größe der Tabelle und der Prädikate aus der WHERE
-Klausel.
mysql>
explain delete from part where p_name is not null;+----+-------------+...+----------+-------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+-------------+ | 1 | SIMPLE |...| 20427936 | Using where | +----+-------------+...+----------+-------------+
Transaktionen und Sperren
Sie können alle Isolationsebenen auf der primären Aurora-Instance verwenden.
Auf Aurora-Reader-DB-Instances gilt die parallele Abfrage für Anweisungen, die unter der REPEATABLE READ
-Isolierungsstufe ausgeführt werden. Aurora My SQL Version 2.09 oder höher kann auch die READ COMMITTED
Isolationsstufe für Reader-DB-Instances verwenden. REPEATABLE READ
ist die Standard-Isolationsstufe für Aurora-Reader-DB-Instances. Um die Isolierungsstufe READ
COMMITTED
auf DB-Leser-Instances anzuwenden, muss die Konfigurationsoption aurora_read_replica_read_committed
auf Sitzungsebene festgelegt werden. Die READ
COMMITTED
Isolationsstufe für Reader-Instances entspricht dem SQL Standardverhalten. Die Isolierung ist jedoch bei Reader-Instances weniger streng als bei Abfragen, welche die READ COMMITTED
-Isolierungsstufe bei der Writer-Instance verwenden.
Weitere Informationen zu Aurora-Isolierungsstufen, insbesondere zu den Unterschieden in READ COMMITTED
zwischen Writer- und Reader-Instances, finden Sie unter Aurora Meine SQL Isolationsstufen.
Nach Abschluss einer großen Transaktion kann es sein, dass die Tabellenstatistik veraltet ist. Für solche Statistiken ist möglicherweise eine ANALYZE TABLE
-Anweisung erforderlich, damit Aurora die Zeilenzahl zuverlässig schätzen kann. Eine umfangreiche DML Anweisung könnte auch einen erheblichen Teil der Tabellendaten in den Pufferpool bringen. Sind diese Daten im Bufferpool kann sein, dass diese Tabelle weniger häufig von Parallel Query abgefragt wird. Dies ändert sich, wenn die Daten aus dem Pool entfernt sind.
Wenn Ihre Sitzung Teil einer langwierigen Transaktion (standardmäßig 10 Minuten) ist, verwenden weitere Abfragen aus dieser Sitzung keine Parallelabfragen. Eine einzelne lang laufende Abfrage kann auch wegen Zeitüberschreitung abgebrochen werden. Dieser Überschreitungsabbruch kann eintreten, wenn die Abfrage länger läuft als zulässig (Höchstdauer derzeit: 10 Minuten), bevor die Parallelverarbeitung der Abfragen beginnt.
Das Risiko, dass lang laufende Transaktionen ungewollt gestartet werden, kann reduziert werden. Legen Sie dazu in autocommit=1
-Sitzungen, in denen Sie Ad-hoc-Abfragen durchführen, die Einstellung mysql
fest. Selbst eine SELECT
-Anweisung gegen eine Tabelle startet eine Transaktion, indem sie eine Leseansicht erstellt. Eine Leseansicht ist ein einheitlicher Datensatz für nachfolgende Abfragen. Dieser bleibt bestehen, bis die Transaktion übernommen wurde. Beachten Sie diese Einschränkung auch bei der Verwendung von JDBC oder ODBC Anwendungen mit Aurora, da solche Anwendungen möglicherweise mit ausgeschalteter autocommit
Einstellung ausgeführt werden.
Im nachfolgenden Beispiel ist zu sehen, wie eine Abfrageausführung gegen eine Tabelle (Einstellung autocommit
deaktiviert) eine Leseansicht erzeugt, die implizit eine Transaktion in Gang setzt. Abfragen, die kurz danach gestartet werden, können Parallel Query noch nutzen. Nach mehreren Minuten kommen Abfragen jedoch nicht mehr für Parallel Query in Frage. Wenn Sie ans Ende der Transaktion COMMIT
oder ROLLBACK
stellen, kann Parallel Query wieder ausgeführt werden.
mysql>
set autocommit=0;mysql>
explain select sql_no_cache count(*) from part where p_retailprice > 10.0;+----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+
mysql>
select sleep(720); explain select sql_no_cache count(*) from part where p_retailprice > 10.0;+------------+ | sleep(720) | +------------+ | 0 | +------------+ 1 row in set (12 min 0.00 sec) +----+...+---------+-------------+ | id |...| rows | Extra | +----+...+---------+-------------+ | 1 |...| 2976129 | Using where | +----+...+---------+-------------+
mysql>
commit;mysql>
explain select sql_no_cache count(*) from part where p_retailprice > 10.0;+----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+
Um festzustellen, wie oft Abfragen nicht für Parallel Query in Frage kamen, weil sie Teil lang laufender Transaktionen waren, untersuchen Sie die Statusvariable Aurora_pq_request_not_chosen_long_trx
.
mysql>
show global status like '%pq%trx%';+---------------------------------------+-------+ | Variable_name | Value | +---------------------------------------+-------+ | Aurora_pq_request_not_chosen_long_trx | 4 | +-------------------------------+-------+
SELECT
-Anweisungen, die Sperren annehmen (z. B. Syntax SELECT FOR UPDATE
oder SELECT LOCK IN SHARE MODE
), können Parallel Query nicht verwenden.
Parallel Query kann an Tabellen funktionieren, die mit einer LOCK TABLES
-Anweisung gesperrt sind.
mysql>
explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055';+----+...+-----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+-----------+----------------------------------------------------------------------------+ | 1 |...| 154545408 | Using where; Using parallel query (3 columns, 1 filters, 0 exprs; 0 extra) | +----+...+-----------+----------------------------------------------------------------------------+
mysql>
explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055' for update;+----+...+-----------+-------------+ | id |...| rows | Extra | +----+...+-----------+-------------+ | 1 |...| 154545408 | Using where | +----+...+-----------+-------------+
B-Baum-Indizes
Die von der ANALYZE TABLE
-Anweisung erfassten Statistiken unterstützen den Optimierer bei der Entscheidung für Parallelabfragen oder Index-Lookups. Ausschlaggebend sind die Eigenschaften der Daten in den Spalten. Halten Sie die Statistiken auf ANALYZE TABLE
dem neuesten Stand, indem Sie DML Operationen nachverfolgen, die wesentliche Änderungen an den Daten in einer Tabelle vornehmen.
Wenn Index-Lookups ausreichen, um eine Abfrage effizient ohne datenintensiven Scan auszuführen, verwendet Aurora möglicherweise Index-Lookups. Dadurch erübrigt sich der Zusatzaufwand der Parallelabfrageverarbeitung. Außerdem regeln Obergrenzen, wie viele Abfragen gleichzeitig in einem Aurora-DB-Cluster zulässig sind. Die Einhaltung bewährter Methoden bei der Indizierung von Tabellen trägt dazu bei, dass in den häufigsten und besonders oft gleichzeitig ausgeführten Abfragen Index-Lookups zur Anwendung kommen.
Indizes für die Volltextsuche (FTS)
Zurzeit wird Parallel Query nicht für Tabellen mit Volltextsuchindex verwendet. Dies gilt unabhängig davon, ob sich die Abfrage auf solche indizierten Spalten bezieht oder ob sie den Operator MATCH
verwendet.
Virtuelle Spalten
Zurzeit wird Parallel Query nicht für Tabellen verwendet, die eine virtuelle Spalte enthalten. Dies gilt unabhängig davon, ob die Abfrage auf virtuelle Spalten verweist.
Integrierte Caching-Mechanismen
Aurora enthält integrierte Caching-Mechanismen: den Bufferpool und den Abfrage-Cache. Der Aurora-Optimierer entscheidet, ob einer dieser Caching-Mechanismen oder Parallel Query für eine bestimmte Abfrage besser geeignet ist.
Wenn eine Parallelabfrage Zeilen filtert und Spaltenwerte transformiert/extrahiert, werden Daten als Tupel an den Hauptknoten zurückübertragen – nicht als Datenseiten. Das bedeutet also, dass bei Verwendung von Parallel Query dem Bufferpool keine Seiten hinzugefügt werden. Es werden auch keine Seiten entfernt, die bereits im Bufferpool sind.
Aurora überprüft die Anzahl der Tabellendatenseiten, die im Pufferpool vorhanden sind und welchen Anteil der Tabellendaten diese Zahl darstellt. Aurora verwendet diese Informationen, um zu bestimmen, ob es effizienter ist, parallele Abfragen zu verwenden (und die Daten im Pufferpool zu umgehen). Es ist auch möglich, dass Aurora den nicht-parallelen Abfrageverarbeitungspfad verwendet, der auf Daten aus dem Bufferpool zurückgreift. Welche Seiten im Cache abgelegt sind und wie sich datenintensive Abfragen auf das Caching und die Bereinigung auswirken, hängt von den Konfigurationseinstellungen des Bufferpools ab. Es kann deshalb schwierig vorherzusagen sein, ob eine Abfrage mit Parallel Query ausgeführt wird. Dies hängt von den Daten im Bufferpool ab, deren Zusammensetzung sich ständig ändert.
Außerdem begrenzt Aurora, wie viele Parallelabfragen gleichzeitig möglich sind. Parallel Query kommt nicht für jede Abfrage zum Einsatz. Deshalb befinden sich die Daten von Tabellen, die von mehreren Abfragen gleichzeitig genutzt werden, zu einem beträchtlichen Teil im Bufferpool. Dementsprechend nutzt Aurora diese Tabellen nicht oft für Parallelabfragen.
In einer Abfolge nicht-paralleler Abfragen gegen dieselbe Tabelle ist die erste Abfrage möglicherweise langsam, weil die Daten nicht im Bufferpool sind. Die zweite und nachfolgende Abfragen laufen bereits schneller ab, weil der Bufferpool inzwischen sozusagen "warmgelaufen" ist. In der Regel zeigen Parallelabfragen ab der ersten Tabellenabfrage gleichbleibende Leistung Für Leistungstests empfehlen sich Vergleichswerte für einen kalten und einen warmen Bufferpool. In einigen Fällen sind die Ergebnisse des warmen Bufferpools eine gute Vergleichsbasis für Parallelabfragezeiten. Berücksichtigen Sie in diesen Fällen Faktoren wie die Häufigkeit von Abfragen für diese Tabelle. Überlegen Sie auch, ob es sich lohnt, die Daten für diese Tabelle im Pufferpool zu behalten.
Der Abfrage-Cache vermeidet die erneute Ausführung einer Abfrage, wenn eine identische Abfrage abgesendet wird und die zugrunde liegenden Tabellendaten nicht geändert wurden. Mit Parallel Query optimierte Abfragen können im Abfrage-Cache abgelegt werden. Wird die gleiche Abfrage noch einmal gestartet, liegt sofort ein Ergebnis vor.
Anmerkung
Bei Leistungsvergleichen können aufgrund des Abfrage-Cache künstlich niedrige Zeitangaben zustandekommen. Für Benchmark-ähnliche Aufgabenstellungen empfiehlt sich der sql_no_cache
-Hinweis. Dieser verhindert, dass das Ergebnis aus dem Abfrage-Cache kommt. Auch dann nicht, wenn die gleiche Abfrage schon einmal ausgeführt wurde. Der Hinweis folgt in der Abfrage unmittelbar nach der SELECT
-Anweisung. Viele Beispiele für parallele Abfragen in diesem Thema enthalten diesen Hinweis, um die Abfragezeiten zwischen den Versionen der Abfrage vergleichbar zu machen, für welche die parallele Abfrage aktiviert und deaktiviert ist.
Entfernen Sie diesen Hinweis aus Ihrem Quellcode, bevor Sie parallele Abfragen in einer Produktionsumgebung verwenden.
Optimierungshinweise
Eine andere Möglichkeit, den Optimierer zu steuern, besteht in der Verwendung von Optimierungshinweisen, die in einzelnen Anweisungen angegeben werden können. Sie können beispielsweise eine Optimierung für eine Tabelle in einer Anweisung aktivieren und dann die Optimierung für eine andere Tabelle deaktivieren. Weitere Informationen zu diesen Hinweisen finden Sie unter Optimizer-Hinweise
Sie können SQL Hinweise mit Aurora SQL My-Abfragen verwenden, um die Leistung zu optimieren. Sie können auch Hinweise verwenden, um zu verhindern, dass Ausführungspläne für wichtige Abfragen aufgrund unvorhersehbarer Bedingungen geändert werden.
Wir haben die SQL Hinweisfunktion erweitert, damit Sie die Optimierer-Optionen für Ihre Abfragepläne kontrollieren können. Diese Hinweise gelten für Abfragen, bei denen die Parallelabfrageoptimierung verwendet wird. Weitere Informationen finden Sie unter Aurora Meine SQL Tipps.
Meine ISAM temporären Tabellen
Die parallele Abfrageausführung ist nur möglich, wenn InnoDB-Tabellen vorliegen. Da Aurora My ISAM hinter den Kulissen für temporäre Tabellen SQL verwendet, verwenden interne Abfragephasen, die temporäre Tabellen beinhalten, niemals parallel Abfragen. Diese Abfragephasen erkennen Sie am Code Using
temporary
in der EXPLAIN
-Ausgabe.