Myskl Server Blog

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.

5.7 – Implicit sort

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).

5.7 – Explicit sort

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.

brug af indeks til at sortere

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 (da ikke vælger denne plan for det datasæt, vi har). Men at bruge denne plan til at gruppere i mangel af et indeks for at få sorterede rækker, og at bruge midlertidig tabel bliver dyrt på grund af et stort antal grupper. Når indekset er tilføjet, det ty til at bruge indekset til at gøre gruppe ved.

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 .

brug af temp table

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.

8.0 – ingen implicit sortering

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 BYimplicit sorterer som standard (det vil sige i fravær afASCellerDESCdesignatorer 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 understøttes ordre ved med ROLLUP. ROLLUP med ORDER BY var ikke tilladt i Myscl 5.7 og tidligere versioner. Så som et alternativ ville brugerne bruge GROUP BY ASC / DESC til at få sorterede data med ROLLUP (selvom sorteringen var meget restriktiv med super aggregerede rækker altid placeret efter de rækker, der blev brugt til at beregne dem i tilfælde af ASC og omvendt for DESC). Vi var nødt til at ophæve denne begrænsning, før vi fjernede støtten til eksplicit sortering for GROUP BY.

tillader nu ordre ved med ROLLUP. Jeg har forklaret i detaljer om, hvordan man kan gøre brug af denne forbedring her. Som forklaret i den samme blog, hvis brugerne ønsker den nøjagtige samme sorteringsrækkefølge af NULLs som i Myskl 5.7 til ROLLUP, skal de bruge gruppering ()-funktionen til at omskrive forespørgslen på en enkel måde.

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 leverede, havde det fint med, at det gik væk.

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!

Related Posts

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *