i Myskl blev GROUP BY historisk set også brugt til at levere sortering. Hvis en forespørgsel er angivet gruppe efter, blev resultatet sorteret som om rækkefølge efter var til stede i forespørgslen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
mysql-5.7> CREATE TABLE t (id INTEGER, cnt INTEGER);
Query OK, 0 rows affected (0.03 sek)
myskl-5.7> indsæt i T-værdier (4,1),(3,2),(1,4),(2,2),(1,1),(1,5),(2,6),(2,1),(1,3),(3,4),(4,5),(3,6);
forespørgsel OK, 12 berørte rækker (0,02 sek)
Records: 12 dubletter: 0 Advarsler: 0
myskl-5.7 > vælg id, SUM (cnt) fra T-gruppe efter id;
+——+———-+
/ id / SUM (cnt) |
+——+———-+
| 1 | 13 |
| 2 | 9 |
| 3 | 12 |
| 4 | 6 |
+——+———-+
4 rækker i sæt (0.00 sec)
|
MySQL here implicitly sorts the results from GROUP BY (i.e. in the absence of ASC
or DESC
designators for GROUP BY
columns ).
MySQL also supported explicit sorting with GROUP BY (i.e. by using explicit ASC
or DESC
designators for GROUP BY
columns).
1
2
3
4
5
6
7
8
9
10
|
mysql-5.7> SELECT id, SUM(cnt) FROM t GROUP BY id DESC;
+——+———-+
/ id / SUM (cnt) |
+——+———-+
| 4 | 6 |
| 3 | 12 |
| 2 | 9 |
| 1 | 13 |
+——+———-+
4 rækker i sæt, 1 ADVARSEL (0,00 sek)
|
Dette er ændret i 8.0, da det ikke længere understøtter hverken implicit eller eksplicit sortering for gruppe efter. I dette blogindlæg vil jeg forklare, hvorfor denne ændring blev nødvendig, og også det arbejde, der blev udført som en forløber for denne ændring.for at gruppere et sæt rækker vælger optimeringsprogrammet forskellige metoder. En af dem er at sortere rækkerne, før de grupperes. Dette gør det nemt at gruppere den ene gruppe efter den anden. Det bliver også billigt, hvis der er et indeks, der kan bruges til at få sorterede rækker. Hvis der ikke er noget indeks, kan vi stadig beslutte at foretage ekstern (filesort) sortering før gruppering.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
31
32
33
34
35
|
myskl-5.7> forklar vælg kvl_big_resultat id, sum(CNT) fra T-gruppe ved id \g
*************************** 1. række ***************************
id: 1
select_type: SIMPLE
tabel: t
partitioner: NULL
rækkefølge: alle
possible_keys: NULL
nøgle: NULL
key_len: NULL
ref: NULL
rows: 12
filtered: 100.00
Extra: Using filesort
1 row in set, 1 warning (0.01 sec)
mysql-5.7> ALTER TABLE t ADD INDEX (id, cnt);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql-5.7> EXPLAIN SELECT id, SUM(cnt) FROM t GROUP BY id \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t
partitions: NULL
type: indeks
possible_keys: id
key_len: 10
ref: NULL
rækker: 12
filtreret: 100.00
ekstra: brug af indeks
1 række i sæt, 1 ADVARSEL (0,00 sek)
|
som det ses i eksemplet, bruger vi ekstern sortering til at gøre gruppe efter. For eksempelforespørgslen har jeg tvunget planen ved at bruge
men at have sorteret rækker før gruppering er ikke en nødvendighed. Optimator kan beslutte at gøre brug af en midlertidig tabel til at gøre det. Hver række i denne tabel vil være en grupperet række, og med hver indgående række opdateres rækken, der svarer til den gruppe i tabellen. Sortering er ikke nødvendig her. Imidlertid, som gruppe efter i Myskl forventedes at sortere, det blev tvunget til at sortere de grupperede rækker, selv i dette tilfælde .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
myskl-5.7> ALTER TABLE t DROP indeks id;
forespørgsel OK, 0 rækker påvirket (0.01 sek)
Records: 0 dubletter: 0 Advarsler: 0
myskl-5.7> forklar vælg id, SUM(cnt) fra T-gruppe efter id \G
*************************** 1. række ***************************
id: 1
select_type: SIMPLE
tabel: t
partitioner: NULL
type: Alle
possible_keys: NULL
nøgle: NULL
key_len: NULL
ref: NULL
rækker: 12
filtreret: 100.00
ekstra: ved hjælp af midlertidig; ved hjælp af filesort
1 række i sæt, 1 ADVARSEL (0.00 sek)
|
i eksempelforespørgslen kan vi se, at selv om midlertidig tabel bruges, myscl gør stadig ekstern sortering. Brugere skal eksplicit angive rækkefølge efter NULL for at lade MYSCL vide, at gruppen ikke behøver at sortere. Så en ikke-standard (rækkefølge efter NULL) syntaks var nødvendig for at modvirke effekten af en anden ikke-standard udvidelse (gruppe ved sortering). Det er meget renere nu, at vi har fjernet den messiness.
fjernelse af implicit sortering for gruppe af
nogen tid tilbage forsøgte jeg at rette fejl 71804. Reporteren forventede ikke at gøre den unødvendige filsortering, den gjorde for GROUP BY. Forsøg på at lave en patch til fejlen fik os til at indse, at optimering af denne særlige situation ikke er meget ligetil på grund af støtten til implicit og eksplicit sortering af denne gruppe efter forudsat. Så vi konkluderede, at før denne optimering kunne gøres, skulle vi re-factoring kode relateret til sortering for gruppe efter.
det første skridt i at gøre det var at fjerne den implicitte sortering for GROUP BY. Som nævnt i brugermanualen her blev det besluttet at fjerne understøttelsen til det nogen tid tilbage . Det er blevet gjort som en del af funktionen faldende indeks i 8.0.
1
2
3
4
5
6
8
9
10
11
12
13
14
15
17
18
19
20
21
22
23
24
25
26
|
> vælg id, SUM (cnt) fra T-gruppe efter id;
+——+———-+
/ id / SUM (cnt) |
+——+———-+
| 4 | 6 |
| 3 | 12 |
| 1 | 13 |
| 2 | 9 |
+——+———-+
4 rækker i sæt (0,00 sek)
myskl> forklar vælg id, SUM(cnt) fra T-gruppe efter id \G
*************************** 1. række ***************************
id: 1
select_type: enkel
tabel: t
partitioner: NULL
type: Alle
possible_keys: NULL
nøgle: NULL
ref: NULL
rækker: 12
filtreret: 100.00
ekstra: ved hjælp af midlertidig
1 række i sæt, 1 advarsel (0,00 sek)
|
som det ses i eksemplet ovenfor, udføres sortering ikke for forespørgslen. Som et resultat sorteres grupperede rækker ikke i det endelige resultat. Hvis brugerne har brug for sorterede rækker, skal de angive rækkefølge efter i forespørgslen.
i 5.7 og under versioner finder brugerne følgende advarsel i manualen.
“GROUP BY
implicit sorterer som standard (det vil sige i fravær afASC
ellerDESC
designatorer tilGROUP BY
kolonner). Dog stole på implicit GROUP BY
sortering (det vil sige sortering i fravær af ASC
eller DESC
designatorer) eller eksplicit sortering for GROUP BY
(det vil sige ved at bruge eksplicit ASC
eller DESC
designatorer til GROUP BY
kolonner) er forældet. For at producere en given sorteringsrækkefølge skal du angive en ORDER BY
klausul. “
fjernelse af eksplicit sortering for gruppe efter
Når det kom til fjernelse af eksplicit sortering, var det lidt mere vanskeligt at gøre det. Vi kunne ikke fjerne det, medmindre
så kort sagt har vi gjort følgende ting som forløbere for at fjerne eksplicit sortering for gruppe efter.
1. Tilføjelse gruppering () funktion
2. Fjernelse af implicit sortering for gruppe med
3. Tillader ordre efter med ROLLUP
og endelig har vi fjernet eksplicit sortering for gruppe efter i 8.0.13.
Vi bad om samfundets mening nogen tid tilbage. Vi konkluderede, at brugere, der var opmærksomme på denne ikke-standardudvidelse, som
konklusion
selvom vi stadig har noget mere arbejde at gøre, før vi løser fejl 71804, er vi glade for, at vi fik dette gjort. Lad os vide dine tanker. Tak fordi du bruger Myskl!