MySQL에서 LIKE를 사용할 때의 실험

5275 단어 MySQL

색인



현재 MySQL은 B+tree 구조로 데이터를 저장하고 있습니다.
B+tree의 이미지는 이런 느낌입니다.



Index를 사용하면, 검색하는 데이터에 도달할 때까지 O(log(n))가 걸리는 것을 알 수 있습니다.
반대로, query에 의해 이 index를 사용하지 않게 되면, 검색량이 O(n)이 되어,
데이터가 커짐에 따라 검색에 시간이 오래 걸릴 수 있습니다.

실험



예를 들어 이런 테이블이 있습니다.
CREATE TABLE table (
    a varchar(255),
    b varchar(255),
    KEY 'a' ('a'),
    KEY 'b' ('b'),
);
mysql> explain select * from table where a LIKE "abc%";
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table     | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | table     | NULL       | range | a             | a    | 1022    | NULL |    1 |   100.00 | Using index condition |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.03 sec)

mysql> explain select * from table where a LIKE "%abc";
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | table     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 49175 |    11.11 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.03 sec)

mysql> explain select * from table where a LIKE "%abc%";
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | table     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 49175 |    11.11 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.03 sec)

암호화된 데이터로 검색하는 경우


Create Table: CREATE TABLE `dummy_table` (
  `dummy_key` varchar(10) DEFAULT NULL,
  KEY `dummy_key` (`dummy_key`)
)
mysql> explain select uuid from dummy_table where AES_DECRYPT(UNHEX(dummy_key), UNHEX('hash_key')) = 'dummy_value';
+----+-------------+-------------+------------+-------+---------------+-----------+---------+------+--------+----------+--------------------------+
| id | select_type | table       | partitions | type  | possible_keys | key       | key_len | ref  | rows   | filtered | Extra                    |
+----+-------------+-------------+------------+-------+---------------+-----------+---------+------+--------+----------+--------------------------+
|  1 | SIMPLE      | dummy_table | NULL       | index | NULL          | dummy_key | 163     | NULL | xxxxxx |   100.00 | Using where; Using index |
+----+-------------+-------------+------------+-------+---------------+-----------+---------+------+--------+----------+--------------------------+

dummy_key를 사용하여 검색하는 경우 함수를 곱해도 index가 사용되었습니다.

결론을 말하면



색인 사용 검색
전방 일치

index를 사용하지 않는 검색
후방 일치 부분 일치

LIKE를 사용하는 경우 정방향 일치를 활용할 수 있는지 여부는 검색 시간 최적화와 관련이 있습니다.

좋은 웹페이지 즐겨찾기