mysql 8.0 [localhost] {msandbox} (test) > create table tbl_alter (a int primary key auto_increment, b int, c int, d varchar(40));
Query OK, 0 rows affected (0.04 sec)
mysql 8.0 [localhost] {msandbox} (test) > insert into tbl_alter (b,c,d) select round(rand()*10)+1, round(rand()*1000)+1, uuid() from information_schema.columns A1, information_schema.columns B2 limit 1000000;
Query OK, 1000000 rows affected (32.68 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
mysql 8.0 [localhost] {msandbox} (test) > select d from tbl_alter order by d desc limit 10;
+--------------------------------------+
| d |
+--------------------------------------+
| 56c11a4e-13cc-11e9-b724-c271ec4ec1de |
| 56c119f4-13cc-11e9-b724-c271ec4ec1de |
| 56c119a4-13cc-11e9-b724-c271ec4ec1de |
| 56c1194a-13cc-11e9-b724-c271ec4ec1de |
| 56c11878-13cc-11e9-b724-c271ec4ec1de |
| 56c11828-13cc-11e9-b724-c271ec4ec1de |
| 56c117e2-13cc-11e9-b724-c271ec4ec1de |
| 56c11792-13cc-11e9-b724-c271ec4ec1de |
| 56c11742-13cc-11e9-b724-c271ec4ec1de |
| 56c116e8-13cc-11e9-b724-c271ec4ec1de |
+--------------------------------------+
10 rows in set (0.43 sec)
mysql 8.0 [localhost] {msandbox} (test) > explain select d from tbl_alter order by d desc limit 10;
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| 1 | SIMPLE | tbl_alter | NULL | ALL | NULL | NULL | NULL | NULL | 995826 | 100.00 | Using filesort |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec)
--^^ 현재 사용랑 수 있는 INDEX가 없음으로, 전체 테이블을 full scan하여 file sort가 진행된 후 10건을 결과로 전달한다.
mysql 8.0 [localhost] {msandbox} (test) > ALTER TABLE tbl_alter ADD INDEX d_idx (d) INVISIBLE;
Query OK, 0 rows affected (2.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
--^^ Index를 INVISIBLE로 만든다.
mysql 8.0 [localhost] {msandbox} (test) > explain select d from tbl_alter order by d desc limit 10;
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| 1 | SIMPLE | tbl_alter | NULL | ALL | NULL | NULL | NULL | NULL | 995826 | 100.00 | Using filesort |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec)
--^^ Index 를 만들었음에도 불구하고 여전히 실행계획이 변하지 않는다.
mysql 8.0 [localhost] {msandbox} (test) > select d from tbl_alter order by d desc limit 10;
+--------------------------------------+
| d |
+--------------------------------------+
| 56c11a4e-13cc-11e9-b724-c271ec4ec1de |
| 56c119f4-13cc-11e9-b724-c271ec4ec1de |
| 56c119a4-13cc-11e9-b724-c271ec4ec1de |
| 56c1194a-13cc-11e9-b724-c271ec4ec1de |
| 56c11878-13cc-11e9-b724-c271ec4ec1de |
| 56c11828-13cc-11e9-b724-c271ec4ec1de |
| 56c117e2-13cc-11e9-b724-c271ec4ec1de |
| 56c11792-13cc-11e9-b724-c271ec4ec1de |
| 56c11742-13cc-11e9-b724-c271ec4ec1de |
| 56c116e8-13cc-11e9-b724-c271ec4ec1de |
+--------------------------------------+
10 rows in set (0.42 sec)
--^^ 여전히 시간이 오래 걸린다.
mysql 8.0 [localhost] {msandbox} (test) > show create table tbl_alter\G
*************************** 1. row ***************************
Table: tbl_alter
Create Table: CREATE TABLE `tbl_alter` (
`a` int(11) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`d` varchar(40) DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `d_idx` (`d`) /*!80000 INVISIBLE */
) ENGINE=InnoDB AUTO_INCREMENT=1048561 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
--^^ 테이블 생성구문을 확인하면, "KEY `d_idx` (`d`) /*!80000 INVISIBLE */" 로 현재 해당 index가 invisible임을 보여준다.
mysql 8.0 [localhost] {msandbox} (test) > SELECT INDEX_NAME, IS_VISIBLE FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'tbl_alter';
+------------+------------+
| INDEX_NAME | IS_VISIBLE |
+------------+------------+
| d_idx | NO |
| PRIMARY | YES |
+------------+------------+
2 rows in set (0.00 sec)
--^^ INFORMATION_SCHEMA.STATISTICS 의 테이블을 조회해도 해당 결과를 얻을 수 있다.
---- 해당 index를 VISIBLE 로 수정하자. 수정은 아주 빠르게 일어난다.
mysql 8.0 [localhost] {msandbox} (test) > ALTER TABLE tbl_alter ALTER INDEX d_idx VISIBLE;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql 8.0 [localhost] {msandbox} (test) > show create table tbl_alter\G
*************************** 1. row ***************************
Table: tbl_alter
Create Table: CREATE TABLE `tbl_alter` (
`a` int(11) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`d` varchar(40) DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `d_idx` (`d`)
) ENGINE=InnoDB AUTO_INCREMENT=1048561 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
--^^ INDEX가 show create 구문에서도 정상적으로 나타난다.
mysql 8.0 [localhost] {msandbox} (test) > explain select d from tbl_alter order by d desc limit 10;
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------+
| 1 | SIMPLE | tbl_alter | NULL | index | NULL | d_idx | 163 | NULL | 10 | 100.00 | Backward index scan; Using index |
+----+-------------+-----------+------------+-------+---------------+-------+---------+------+------+----------+----------------------------------+
1 row in set, 1 warning (0.00 sec)
--^^ 정상적인 실행계획이 나타난다.
mysql 8.0 [localhost] {msandbox} (test) > select d from tbl_alter order by d desc limit 10;
+--------------------------------------+
| d |
+--------------------------------------+
| 56c11a4e-13cc-11e9-b724-c271ec4ec1de |
| 56c119f4-13cc-11e9-b724-c271ec4ec1de |
| 56c119a4-13cc-11e9-b724-c271ec4ec1de |
| 56c1194a-13cc-11e9-b724-c271ec4ec1de |
| 56c11878-13cc-11e9-b724-c271ec4ec1de |
| 56c11828-13cc-11e9-b724-c271ec4ec1de |
| 56c117e2-13cc-11e9-b724-c271ec4ec1de |
| 56c11792-13cc-11e9-b724-c271ec4ec1de |
| 56c11742-13cc-11e9-b724-c271ec4ec1de |
| 56c116e8-13cc-11e9-b724-c271ec4ec1de |
+--------------------------------------+
10 rows in set (0.00 sec)
--^^ 결과도 빠르게 나타난다.
mysql 8.0 [localhost] {msandbox} (test) > ALTER TABLE tbl_alter ALTER INDEX d_idx INVISIBLE;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql 8.0 [localhost] {msandbox} (test) > explain select d from tbl_alter order by d desc limit 10;
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| 1 | SIMPLE | tbl_alter | NULL | ALL | NULL | NULL | NULL | NULL | 995826 | 100.00 | Using filesort |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec)
--^^ ALTER INDEX d_idx INVISIBLE 구문을 통해 다시 해당 INDEX를 INVISIBLE로 변경할 수 있다.