MySQL 쿼리 최적화를 위한 사용자 정의 변수 사용

정렬 조회 최적화


사용자 정의 변수의 중요한 특성 중 하나는 이 변수의 수학적 계산 결과를 동시에 이 변수에 값을 부여할 수 있다는 것이다. 이것은 우리의 i=i+1과 유사하다.다음은 데이터 테이블 행 번호를 계산하는 예입니다.

SET @rownum := 0;
SELECT actor_id, @rownum := @rownum + 1 AS rownum
FROM sakila.actor LIMIT 3;
actor_id
rownum






얻은 결과는 아무런 의미가 없어 보일 수도 있다. 이것은 메인 키가 1에서 증가했기 때문에 줄 번호와 메인 키 값이 같기 때문이다.그러나 이런 방식은 정렬에 사용할 수 있다.예를 들어 가장 많은 영화를 연기한 10명의 배우를 조회해야 하는데, 일반적인 방법은 다음과 같다.

SELECT actor_id, COUNT(*) as cnt
FROM sakila.film_actor
GROUP BY actor_id
ORDER BY cnt DESC
LIMIT 10;
얻은 결과는 아무런 의미가 없어 보일 수도 있다. 이것은 메인 키가 1에서 증가했기 때문에 줄 번호와 메인 키 값이 같기 때문이다.그러나 이런 방식은 정렬에 사용할 수 있다.예를 들어 가장 많은 영화를 연기한 10명의 배우를 조회해야 하는데, 일반적인 방법은 다음과 같다.

SELECT actor_id, COUNT(*) as cnt
FROM sakila.film_actor
GROUP BY actor_id
ORDER BY cnt DESC
LIMIT 10;
만약 우리가 상응하는 순위 값을 얻으려면 변수를 도입하여 완성할 수 있다.

SET @curr_cnt := 0, @prev_cnt := 0, @rank := 0;
SELECT actor_id,
	@curr_cnt := cnt AS cnt,
  @rank 		:= IF(@prev_cnt <> @curr_cnt, @rank+1, @rank) as rank,
  @prev_cnt	:= @curr_cnt AS dummy
FROM (
  SELECT actor_id, COUNT(*) AS cnt
  FROM sakila.film_actor
	GROUP BY actor_id
	ORDER BY cnt DESC
	LIMIT 10
) as der;
여기는 영화의 수를 curr_에게 부여한 거예요.cnt 변수,prev_ 사용cnt는 이전 배우의 출연 수량을 저장한다.순위는 1위부터 시작하며, 뒤에 있는 배우의 수가 이전 배우의 수와 다르면 순위는 아래(+1)로 내려가고, 같으면 이전 배우의 순위와 같다.이런 방식을 통해 검색 결과에서 배우의 순위를 직접 얻을 수 있고 데이터베이스에서 2차 처리를 할 필요가 없다.

방금 수정한 데이터 줄을 반복해서 가져오는 것을 피하다


데이터 줄을 업데이트할 때 데이터 줄의 정보를 다시 얻으려면 데이터베이스를 한 번 더 읽어야 한다.이는 MySQL이 PostgreSQL의 UPDATE RETURNING 기능과 달리 업데이트된 데이터 줄을 동시에 되돌릴 수 있기 때문이다.그러나 우리는 사용자 정의 변수를 통해 이런 조작을 완성할 수 있다.예를 들어 업데이트 시간이 방금 수정된 줄을 가져오고 사용자 정의 변수를 사용하지 않으면 추가 조회를 해야 합니다.

UPDATE tb1 SET lastUpdated = NOW() WHERE id = 1;
SELECT lastUpdated FROM tb1 WHERE id = 1;
사용자 정의 변수를 사용할 때 이러한 상황을 피할 수 있습니다.

UPDATE tb1 SET lastUpdated = NOW() WHERE id = 1 AND @now  := NOW();
SELECT @now;
비록 여전히 조회 조작이 하나 있지만, 뒤의 조회 조작은 더 이상 데이터베이스에 접근할 필요가 없다.

게으름 피우는 연합 조회


만약 우리가 연합 조회를 써서 다음과 같은 작업을 완성해야 한다고 가정하자. 연합 지점에서 일치하는 데이터 줄을 찾고 찾으면 다른 지점을 건너뛴다.y이런 상황은 핫스팟 데이터나 저주파 접근 데이터에서 찾아야 한다(예를 들어 최근 주문서와 역사 주문서).다음은 사용자를 위한 일반적인 SQL입니다.

SELECT id FROM users WHERE  id = 123
UNION ALL
SELECT id FROM users_archived WHERE id = 123;
이 조회는 현재 사용 중인 사용자 테이블에서 id가 123인 사용자를 조회한 다음 압축된 사용자 테이블에서 같은 id의 사용자를 찾습니다.그러나 이런 작법은 비교적 효과가 없다. 사용자 테이블에서 찾고 싶은 사용자를 찾았더라도users_archived 이 시계는 다시 한 번 찾습니다. 실제 사용자 id가 123인 경우 그 중의 한 표나 두 표의 데이터만 존재합니다.게으르게 불러오는 연합 조회를 통해 이런 상황을 피할 수 있다. 첫 번째 지점에서 데이터를 찾지 못했을 때만 두 번째 지점에서 조회할 수 있다.따라서 데이터 열이 많이 반환되지 않도록 MySQL의 GREATEST 방법을 검색 결과의 컨테이너로 사용할 수 있습니다.

SELECT GREATEST(@found := -1, id) AS id, users.name, 'users' as which_tb1
FROM users WHERE id = 123
UNION ALL
	SELECT id, users_archived.name, 'users_archived'
  FROM users_archived WHERE id = 123 AND @found IS NULL
UNION ALL
	SELECT 1, '', 'reset' FROM DUAL WHERE ( @found := NULL) IS NOT NULL;
상술한 조회가 첫 줄에 결과가 있으면 @found는 값을 부여하지 않기 때문에 NULL이므로 두 번째 조회를 실행합니다.세 번째 UNION은 실제 효과가 없습니다. @found를 NULL 값으로 복구하여 이 SQL을 반복할 수 있도록 하기 위해서입니다.또 다른 검증 방법은 같은 테이블에 대해 이런 조작을 하면 실제적으로 한 줄의 데이터만 되돌려주거나 되돌려주지 않는다는 것을 발견할 수 있다.

SELECT GREATEST(@found := -1, `id`) AS `id`, `infocenter_city`.`name`, 'city' as which_tb1 
FROM `infocenter_city` WHERE `id` = 460100 
UNION ALL 
	SELECT `id`, `infocenter_city`.`name`, 'infocenter_city' 
	FROM `infocenter_city` WHERE id = 460100 AND @found IS NULL 
UNION ALL 
	SELECT 1, '', 'reset' FROM DUAL WHERE ( @found := NULL) IS NOT NULL
이상은 MySQL이 사용자 정의 변수를 사용하여 조회 최적화를 하는 상세한 내용입니다. 더 많은 MySQL이 사용자 정의 변수로 조회 최적화를 하는 것에 관한 자료는 저희 다른 관련 글을 주목해 주십시오!

좋은 웹페이지 즐겨찾기