Closed hyeonprojects closed 1 year ago
DB가 돌아가는 원리를 생각하면 되는데, 저는 나름 최적화가 잘 되어서 SQL 구문이 짧고 JOIN문이 많이 없을 수록 최적화가 잘 될거라고 생각했습니다.
예를 들면 아래와 같은 코드가 원래 생각한 SQL 쿼리문이였습니다.
SELECT *,
ST_DISTANCE_SPHERE(POINT(129.0832792851, 35.2424891575), POINT(r.restaurant_x, r.restaurant_y)) as distance
FROM restaurant r
JOIN opening_time ot on r.restaurant_id = ot.restaurant_id
WHERE r.restaurant_address LIKE '%%장전동%%'
ORDER BY distance
LIMIT 0, 10;
일단 함수형 프로그래밍의 장점과 특성처럼 최적화는 DBMS가 잘할거라는 생각을 가지고 있었죠. (함수형 프로그래밍 논문을 읽어보면 최적화나 작업 효율을 좀 더 컴퓨터에 할당하는 방식입니다.)
그러나 아래의 쿼리가 어느 정도 더 빨랐습니다.
SELECT anon_1.restaurant_id,
anon_1.restaurant_name,
anon_1.restaurant_rate,
anon_1.restaurant_category,
anon_1.restaurant_count_seats,
anon_1.restaurant_x,
anon_1.restaurant_y,
anon_1.restaurant_address,
anon_1.restaurant_description,
anon_1.restaurant_contact,
anon_1.restaurant_created_at,
anon_1.restaurant_updated_at,
anon_1.restaurant_image,
anon_1.restaurant_menu,
anon_1.st_distance_sphere_1,
opening_time_1.opening_time_id,
opening_time_1.restaurant_id AS restaurant_id_1,
opening_time_1.restaurant_opening_time_days,
opening_time_1.restaurant_opening_time,
opening_time_1.restaurant_break_time_days,
opening_time_1.restaurant_break_time,
opening_time_1.opening_time_created_at,
opening_time_1.opening_time_updated_at
FROM (SELECT restaurant.restaurant_id AS restaurant_id,
restaurant.restaurant_name AS restaurant_name,
restaurant.restaurant_rate AS restaurant_rate,
restaurant.restaurant_category AS restaurant_category,
restaurant.restaurant_count_seats AS restaurant_count_seats,
restaurant.restaurant_x AS restaurant_x,
restaurant.restaurant_y AS restaurant_y,
restaurant.restaurant_address AS restaurant_address,
restaurant.restaurant_description AS restaurant_description,
restaurant.restaurant_contact AS restaurant_contact,
restaurant.restaurant_created_at AS restaurant_created_at,
restaurant.restaurant_updated_at AS restaurant_updated_at,
restaurant.restaurant_image AS restaurant_image,
restaurant.restaurant_menu AS restaurant_menu,
st_distance_sphere(point(129.0832792851, 35.2424891575),
point(restaurant.restaurant_x, restaurant.restaurant_y)) AS st_distance_sphere_1
FROM restaurant
INNER JOIN opening_time ON restaurant.restaurant_id = opening_time.restaurant_id
WHERE restaurant.restaurant_address LIKE '%%장전동%%'
ORDER BY st_distance_sphere(point(129.0832792851, 35.2424891575), point(restaurant.restaurant_x, restaurant.restaurant_y))
LIMIT 0, 10) AS anon_1
INNER JOIN opening_time AS opening_time_1 ON anon_1.restaurant_id = opening_time_1.restaurant_id
ORDER BY anon_1.st_distance_sphere_1;
사실 두 차이는 크게 차이가 나지 않습니다. 간단하게 첫번쨰 짧은 쿼리는 약 2s 400ms 쯤이라면 아래 쿼리는 2s 200ms 쯤입니다. 데이터가 많아질수록 더 커지겠죠.
위 데이터가 왜 느릴까요? 제가 추측하기로 2가지 방향으로 추측이 되는데 간단하게 컴퓨터가 저장소에 돌아가는 원리와 DBMS가 돌아가는 원리를 생각해보면 좋을거 같습니다. (이는 언어 컴파일원리를 생각해보면 쉽게 나옵니다.)
허허
한일
쿼리 안 돌아가는 이유
MariaDB는 비교적 최근 버전에 좌표 관련 기능을 지원해서 MariaDB 업데이트 했습니다.
쿼리 최적화 방법
필요없는 JOIN을 하나 없앰. (단순하죠?)
아래가 기본 ORM에서 나오는 쿼리문입니다.
변경 된 ORM의 쿼리는 아래와 같습니다.