a MySQL, történelmileg csoport által használták, hogy a válogatás is. Ha egy lekérdezés megadott csoport, az eredmény volt rendezve, mintha sorrendben volt jelen a lekérdezésben.
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 sec)
mysql-5.7> BESZÚRÁS A t ÉRTÉKEK (4,1),(3,2),(1,4),(2,2),(1,1),(1,5),(2,6),(2,1),(1,3),(3,4),(4,5),(3,6);
Lekérdezés OK, 12 sor érintett (0.02 sec)
Bejegyzések: 12 Másolatok: 0 Figyelmeztetések: 0
mysql-5.7> SELECT id, SUM(cnt) A t-CSOPORT ÁLTAL id;
+——+———-+
| id | SUM(cnt) |
+——+———-+
| 1 | 13 |
| 2 | 9 |
| 3 | 12 |
| 4 | 6 |
+——+———-+
4, amellyel a set (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, amellyel a set, 1 figyelmeztetés (0.00 sec)
|
Ez a megváltozott 8.0, mivel nem támogatja vagy implicit vagy explicit válogatás a CSOPORT ÁLTAL. Ebben a blogbejegyzésben elmagyarázom, miért vált szükségessé ez a változás, valamint a változás előfutáraként végzett munka.
csoport a MySQL
a sorok csoportosításához a MySQL optimizer különböző módszereket választ. Az egyik az, hogy rendezze a sorokat, mielőtt csoportosítaná őket. Ez megkönnyíti a csoport egyik csoport a másik után. Ez is lesz olcsó, ha van egy index, hogy lehet használni, hogy válogatott sorok. Ha nincs index, a MySQL optimizer továbbra is dönthet úgy, hogy csoportosítás előtt külső (filesort) rendezést végez.
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
30
31
32
33
34
35
|
mysql-5.7> MAGYARÁZNI, VÁLASSZA a SQL_BIG_RESULT id ÖSSZEG(cnt) A t-CSOPORT az id \G
*************************** 1. sor ***************************
id: 1
select_type: SIMPLE
táblázat: t
partíciók: NULL
rend: ALL
possible_keys: NULL
kulcs: 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
típusa: index
possible_keys: id
kulcs: id
key_len: 10
ref: NULL
sorok: 12
szűrt: 100.00
Extra: A index
1 sorban, a set, 1 figyelmeztetés (0.00 sec)
|
Ahogy a példában látjuk is, mielőtt hozzá index az asztalra, MySQL használ külső válogatás a CSOPORT ÁLTAL. A példakérdéshez az sql_big_result használatával kényszerítettem a tervet (mivel a MySQL nem választja ezt a tervet a meglévő adatkészlethez). De a MySQL ezt a tervet arra használná, hogy index hiányában csoportosítsa a sorokat, az ideiglenes táblázat használata pedig sok csoport miatt költséges lesz. Miután az index hozzáadásra került, az index használatával csoportosítható.
de a sorok rendezése a csoportosítás előtt nem szükséges. Optimalizáló dönthet úgy, hogy használja az ideiglenes táblázat csinálni. A táblázat minden sora egy csoportosított sor lenne, és minden bejövő sor esetén a táblázatban az adott csoportnak megfelelő sor frissül. Itt nincs szükség válogatásra. Mivel azonban a MySQL csoportosítása várhatóan rendeződik, ebben az esetben is kénytelen volt rendezni a csoportosított sorokat .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
mysql-5.7> ALTER TABLE t DROP INDEX id;
Query OK, 0 sor érintett (0.01 sec)
Records: 0 ismétlődések: 0 Figyelmeztetések: 0
mysql-5.7> magyarázd SELECT id, SUM(cnt) FROM T GROUP by id \g
*************************** 1. sor ***************************
id: 1
select_type: SIMPLE
táblázat: t
partíciók: NULL
Típus: minden
possible_keys: NULL
kulcs: NULL
key_len: NULL
ref: NULL sorok: 12
szűrt: 100.00
Extra: ideiglenes Használata; A filesort
1 sorban, a set, 1 figyelmeztetés (0.00 sec)
|
a példa lekérdezés, láthatjuk, hogy bár ideiglenes asztal használt, MySQL még mindig külső válogatás. A felhasználóknak kifejezetten meg kell határozniuk a null sorrendjét, hogy a MYSQL tudja, hogy a csoportnak nem kell rendeznie. Tehát egy nem szabványos (null szerinti sorrend) szintaxisra volt szükség egy másik nem szabványos kiterjesztés (csoport rendezéssel) hatásának ellensúlyozásához. Sokkal tisztább most, hogy megszüntettük ezt a rendetlenséget.
eltávolítása implicit válogatás csoport
egy ideje vissza próbáltam kijavítani bug 71804. A riporter arra számított, hogy a MySQL nem végzi el a felesleges fájlt-rendezze, amit a csoport számára készített. A hiba javításának megpróbálása ráébresztett minket arra, hogy ennek a helyzetnek az optimalizálása nem túl egyenesen előre, mert támogatja a csoport által biztosított implicit és explicit rendezést. Tehát arra a következtetésre jutottunk, hogy mielőtt ezt az optimalizálást elvégezhetnénk,újra kell faktoring kódot a csoport szerinti rendezéshez.
ennek első lépése az volt, hogy eltávolítsa a csoport implicit rendezését. Amint azt a felhasználói kézikönyv itt említi, úgy döntöttek, hogy egy ideje eltávolítják a támogatást . Ezt a 8.0-ban a csökkenő index jellemző részeként hajtották végre.
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
|
mysql> SELECT id, SUM(cnt) A t-CSOPORT ÁLTAL id;
+——+———-+
| id | SUM(cnt) |
+——+———-+
| 4 | 6 |
| 3 | 12 |
| 1 | 13 |
| 2 | 9 |
+——+———-+
4, amellyel a set (0.00 sec)
mysql> MAGYARÁZNI, VÁLASSZUK az id, SUM(cnt) A t-CSOPORT az id \G
*************************** 1. sor ***************************
id: 1
select_type: SIMPLE
táblázat: t
partíciók: NULL
típus: MIND
possible_keys: NULL
kulcs: NULL
key_len: NULL
ref: NULL
sorok: 12
szűrt: 100.00
Extra: Használatával ideiglenesen
1 sorban, a set, 1 figyelmeztetés (0.00 sec)
|
a fenti példában, rendezése nem történik a lekérdezés. Ennek eredményeként a csoportosított sorok nem kerülnek rendezésre a végeredményben. Ha a felhasználóknak rendezett sorokra van szükségük, akkor a lekérdezésben meg kell adniuk a sorrendet.
A MySQL 5.7 vagy az alábbi verziók, a felhasználók megtalálják a következő figyelmeztetést a kézikönyvben.
“GROUP BY
implicit módon alapértelmezés szerint rendezi (azazASC
vagyDESC
GROUP BY
oszlopok). Azonban támaszkodva implicit GROUP BY
rendezés (a rendezés hiányában ASC
vagy DESC
jelzőket) vagy kifejezett rendezés GROUP BY
(ez, segítségével explicit ASC
vagy DESC
jelzőket a GROUP BY
oszlopok) elavulttá. Egy adott rendezési sorrend létrehozásához adjon meg egy ORDER BY
záradékot. “
eltávolítása explicit rendezési csoport
amikor eltávolítása explicit rendezési, ez egy kicsit trükkös csinálni. Nem tudtuk eltávolítani, kivéve, ha a MySQL által támogatott sorrendben a ROLLUP. A MySQL 5.7-es vagy korábbi verzióiban nem volt engedélyezett a megrendelés. Olyan, mint egy alternatív, a felhasználók használja CSOPORT ASC/DESC hogy rendezett adatokat ÖSSZESÍTŐ (Bár a rendezés nagyon korlátozó szuper összesített sorok mindig elhelyezett után a sorok kiszámításához használt őket abban az esetben, ASC, illetve fordítva DESC). Ezt a korlátozást meg kellett szüntetnünk, mielőtt eltávolítottuk a csoport kifejezett válogatásának támogatását.
a MySQL most lehetővé teszi a rendelést a ROLLUP segítségével. Részletesen elmagyaráztam, hogyan lehet kihasználni ezt a javulást itt. Amint azt ugyanabban a blogban kifejtettük, ha a felhasználók pontosan ugyanazt a rendezési sorrendet akarják, mint a MySQL 5.7 a ROLLUP esetében, akkor a csoportosítás() funkciót kell használniuk a lekérdezés egyszerű módon történő újraírásához.
tehát röviden a következő dolgokat tettük előfutárként, hogy eltávolítsuk a csoport által kifejezett válogatást.
1. Csoportosítás () függvény hozzáadása
2. A csoport implicit válogatásának eltávolítása
3. Lehetővé teszi annak érdekében, hogy a ROLLUP
végül eltávolítottuk explicit rendezési csoport által a MySQL 8.0.13.
egy ideje kértük a közösségek véleményét. Arra a következtetésre jutottunk, hogy azok a felhasználók, akik tisztában voltak ezzel a nem szabványos kiterjesztéssel, amelyet a MySQL biztosított, rendben vannak vele.
következtetés
bár még van néhány tennivalónk a 71804-es hiba kijavítása előtt, örülünk, hogy ezt megtettük. Kérjük, ossza meg velünk a gondolatait. Köszönjük, hogy a MySQL!