2018年11月6日火曜日

MySQL 8.0では「GROUP BYによる暗黙のソート」がされなくなるよ

MySQL 5.7の時点で既に宣言はされていた。
GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators), but relying on implicit GROUP BY sorting in MySQL 5.7 is deprecated.
どういうことが起こるかというと、こう。
$ perl -ML -E 'for (my $n= 1; $n <= 10; $n++) { for (my $m= 1; $m <= 100; $m++) { printf("%d\t%d\n", $n, $m) } }' | sort -R > /tmp/seq

mysql80 165> CREATE TABLE t1 (n int, m int);
Query OK, 0 rows affected (0.05 sec)

mysql80 165> LOAD DATA INFILE '/tmp/seq' INTO TABLE t1;
Query OK, 1000 rows affected (0.09 sec)
Records: 1000  Deleted: 0  Skipped: 0  Warnings: 0

mysql80 165> SELECT * FROM t1 LIMIT 10;
+------+------+
| n    | m    |
+------+------+
|    2 |   18 |
|    4 |    7 |
|    6 |   85 |
|    1 |   69 |
|    4 |   66 |
|    7 |   52 |
|    3 |   25 |
|    2 |   19 |
|    1 |   61 |
|    5 |   80 |
+------+------+
10 rows in set (0.01 sec)
こんなデータに対して、 SELECT n, COUNT(m) FROM t1 GROUP BY n とか打つ。
今まではこうだった。
mysql57 11> SELECT n, COUNT(m) FROM t1 GROUP BY n;
+------+----------+
| n    | COUNT(m) |
+------+----------+
|    1 |      100 |
|    2 |      100 |
|    3 |      100 |
|    4 |      100 |
|    5 |      100 |
|    6 |      100 |
|    7 |      100 |
|    8 |      100 |
|    9 |      100 |
|   10 |      100 |
+------+----------+
10 rows in set (0.00 sec)
これからはこうなる。
mysql80 165> SELECT n, COUNT(m) FROM t1 GROUP BY n;
+------+----------+
| n    | COUNT(m) |
+------+----------+
|    2 |      100 |
|    4 |      100 |
|    6 |      100 |
|    1 |      100 |
|    7 |      100 |
|    3 |      100 |
|    5 |      100 |
|   10 |      100 |
|    9 |      100 |
|    8 |      100 |
+------+----------+
10 rows in set (0.00 sec)
よく見ると n は「見つかった順」にはなっているから、 KEY (n) を追加してそのインデックスを使わせて GROUP BY n すれば n でソート済にはなるんだけど、オプティマイザーのご機嫌とか伺いながらになるようなそんな手は選べない。
おとなしく ORDER BY を足しましょう。
mysql80 165> SELECT n, COUNT(m) FROM t1 GROUP BY n ORDER BY n;
+------+----------+
| n    | COUNT(m) |
+------+----------+
|    1 |      100 |
|    2 |      100 |
|    3 |      100 |
|    4 |      100 |
|    5 |      100 |
|    6 |      100 |
|    7 |      100 |
|    8 |      100 |
|    9 |      100 |
|   10 |      100 |
+------+----------+
10 rows in set (0.00 sec)

0 件のコメント :

コメントを投稿