개발자가 되고 싶은 준개발자

[MySQL] MySQL 8.0.25 버전 Prepared Statement가 index 못 타는 버그 본문

MySQL/mysql

[MySQL] MySQL 8.0.25 버전 Prepared Statement가 index 못 타는 버그

준개발자 2023. 7. 17. 20:35

 

MySQL 8.0.25버전에서 Prepared statement가 index 못 타는 버그를 발견하여 버전 업그레이드를 하게 되었다.


Prepared Statement란?

Prepared Statement란 파라미터를 미리 채우지 않고, 공란으로 둔 후에 값을 따로 덧붙여서 쿼리하는 방식이다.

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;

위 처럼 값을 쿼리에서 분리해서 따로 쓰게 되면 SQL Ingection 공격을 피할 수 있어 보안상으로도 좋다. 또한 똑같은 쿼리를 값만 바꾸어 여러 개의 쿼리로 실행하는 경우가 많은데 이 경우에 동일한 쿼리를 매번 파싱하지 않아도 되기 때문에 효율적이다.


 

최근에 특정 쿼리에서 Prepared Statement를 사용할 때는 수십초가 걸리고, 값들을 다 채워서 일반 쿼리로 하면 순간에 끝나서 원인을 찾아달라는 요청이 왔었다.

실제로 두 가지 case를 Query Explain을 통해서 분석으로 해보니 인덱스를 사용하지 못해 where절과 order by 절에서 각각 10초 이상의 소요되었다.


원인?

원인은 생각보다 간단했다. 버전 이슈였다.

 

아래 버그 report에서 볼 수 있듯이 8.0.25버전에서는 Prepared Statement의 경우 optimizer가 제 역할을 못 하는 경우가 있었다.

-버그: https://bugs.mysql.com/bug.php?id=103711

 

이 버그는 다행히 다음 버전에서 바로 patch 되어 버전을 올리니 Prepared Statement도 index를 사용하게 되었다.

-버그 patch: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-26.html

(Prepared statements did not always make use of index extensions (see Use of Index Extensions). (Bug #103711, Bug #32897525))