Amazon Aurora MySQL용 Parallel Query 처리 - Amazon Aurora

Amazon Aurora MySQL용 Parallel Query 처리

이 주제에서는 Amazon Aurora MySQL 호환 버전의 병렬 쿼리 성능 최적화에 대해 설명합니다. 이 기능은 특정 데이터 집약적인 쿼리를 위한 특수한 처리 경로를 사용하면서 Aurora 공유 스토리지 아키텍처를 활용합니다. 병렬 쿼리는 수만 개의 행이 포함된 테이블이 있는 Aurora MySQL DB 클러스터 및 완료되기까지 몇 분 또는 몇 시간이 걸리는 분석 쿼리에서 가장 잘 작동합니다.

Aurora MySQL용 Parallel Query 개요

Aurora MySQL 병렬 쿼리는 데이터 집약적인 쿼리 처리에 수반되는 I/O 및 컴퓨팅의 일부를 병렬화하는 최적화입니다. 병렬화되는 작업은 스토리지로부터 행 검색, 열 값 추출, 어떤 행이 WHERE 절 및 JOIN 절의 조건과 일치하는지 판단을 포함합니다. 이 데이터 집약적인 작업은 Aurora 분산 스토리지 계층의 여러 노드에 위임됩니다(데이터베이스 최적화 용어로는 푸시 다운됩니다). 병렬 쿼리가 없으면, 각 쿼리가 스캔한 모든 데이터를 Aurora MySQL 클러스터(헤드 노드) 내의 단일 노드로 가져오고 거기에서 모든 쿼리 처리를 수행합니다.

작은 정보

PostgreSQL 데이터베이스 엔진에도 '병렬 쿼리'라는 기능이 있습니다. 해당 기능은 Aurora 병렬 쿼리와 관련이 없습니다.

병렬 쿼리 기능을 설정하면 Aurora MySQL 엔진이 힌트 또는 테이블 속성과 같은 SQL 변경의 필요 없이 쿼리가 혜택을 얻을 수 있는 경우를 자동으로 결정합니다. 다음 단원에는서 병렬 쿼리가 쿼리에 적용되는 경우에 대한 설명을 확인할 수 있습니다. 또한 병렬 쿼리가 가장 많은 혜택을 제공하는 경우에 적용되게 하는 방법도 확인할 수 있습니다.

참고

병렬 쿼리 최적화는 완료하는 데 몇 분 또는 몇 시간이 걸리는 장기 실행 쿼리에 가장 큰 이점을 제공합니다. Aurora MySQL은 일반적으로 비용이 적게 드는 쿼리에 대해 병렬 쿼리 최적화를 수행하지 않습니다. 또한 쿼리 캐싱, 버퍼 풀 캐싱, 인덱스 조회를 비롯한 다른 최적화 기술이 더 적합한 경우에도 일반적으로 병렬 쿼리 최적화를 수행하지 않습니다. 병렬 쿼리가 사용될 것으로 예상될 때 사용되고 있지 않은 경우 어떤 문이 병렬 쿼리를 사용하는지 확인 단원을 참조하세요.

이점

병렬 쿼리를 사용하면 Aurora MySQL 테이블에 대해 데이터 집약적인 분석 쿼리를 실행할 수 있으며, 대부분의 경우 쿼리 처리를 위한 전통적인 작업 분할에 비해 획기적인 성능 향상이 나타날 수 있습니다.

병렬 쿼리의 이점은 다음과 같습니다.

  • 여러 스토리지 노드에 걸친 물리적 읽기 요청을 병렬화하여 I/O 성능 개선

  • 네트워크 트래픽 감소. Aurora는 전체 데이터 페이지를 스토리지 노드로부터 헤드 노드로 전송한 다음 그 후에 불필요한 행과 열을 필터링하지 않습니다. 대신, Aurora은 결과 집합에 필요한 열 값만 포함된 간소화된 튜플을 전송합니다.

  • 푸시 다운 기능 처리, 행 필터링 및 WHERE 절에 대한 열 프로젝션으로 인한 헤드 노드에 대한 CPU 사용량의 감소.

  • 버퍼 풀에서의 메모리 압력 감소. 병렬 쿼리에 의해 처리된 페이지는 버퍼 풀에 추가되지 않으므로 데이터 집약적인 스캔 중 버퍼 풀에서 자주 사용되는 데이터가 제거될 가능성이 감소됩니다.

  • 기존 데이터에 대한 장기 실행 분석 쿼리 수행이 유용해진 덕분에 추출, 변환, 로드(ETL) 파이프라인에서 데이터 중복의 잠재적 감소.

아키텍처

병렬 쿼리 기능은 Aurora MySQL의 주요 아키텍처 원칙을 사용합니다. 스토리지 하위 시스템으로부터 데이터베이스 엔진의 결합 해제 및 통신 프로토콜을 간소화하여 네트워크 트래픽을 감소합니다. Aurora MySQL은 이러한 기법을 사용하여 다시 실행 로그 처리와 같은 쓰기 집약적인 작업의 속도를 높입니다. 병렬 쿼리는 읽기 작업에도 동일한 원칙을 적용합니다.

참고

Aurora MySQL 병렬 쿼리의 아키텍처는 다른 데이터베이스 시스템에서 이름이 유사한 기능의 아키텍처와는 다릅니다. Aurora MySQL 병렬 쿼리는 SMP(대칭적 다중 처리)를 포함하지 않으며 따라서 데이터베이스 서버의 CPU 용량에 의존하지 않습니다. 병렬 처리는 쿼리 조정자 역할을 하는 Aurora MySQL 서버와는 독립적인 스토리지 계층에서 일어납니다.

기본적으로, 병렬 쿼리를 사용하지 않을 경우 Aurora 쿼리에 대한 처리는 원시 데이터를 Aurora 클러스터 내 단일 노드(헤드 노드)로 전송합니다. 그런 다음 Aurora는 해당 단일 노드의 단일 스레드에서 해당 쿼리에 대해 추가되는 모든 처리를 수행합니다. 병렬 쿼리를 사용할 경우, 이러한 I/O 집약적이고 CPU 집약적인 작업의 대부분이 스토리지 계층의 노드로 위임됩니다. 행은 이미 필터링되고 열 값은 이미 추출되어 전송된 상태로, 결과 집합의 간소화된 행만 다시 헤드 노드로 전송됩니다. 성능 혜택은 네트워크 트래픽의 감소, 헤드 노드에서 CPU 사용량의 감소, 및 스토리지 노드 전체에서 I/O 병렬화로부터 비롯됩니다. 병렬 I/O, 필터링 및 프로젝션의 양은 쿼리를 실행하는 Aurora 클러스터의 DB 인스턴스 수와 무관합니다.

필수 조건

병렬 쿼리의 모든 기능을 사용하려면 버전 2.09 이상을 실행하는 Aurora MySQL DB 클러스터가 필요합니다. 병렬 쿼리와 함께 사용하려는 클러스터가 이미 있는 경우 호환 가능한 버전으로 업그레이드하고 나중에 병렬 쿼리를 설정할 수 있습니다. 이 경우 해당 최신 버전에서는 구성 설정 이름 및 기본값이 다르기 때문에 병렬 쿼리를 위한 업그레이드 고려 사항의 업그레이드 절차를 따라야 합니다.

클러스터의 DB 인스턴스는 db.r* 인스턴스 클래스를 사용해야 합니다.

클러스터에 대해 해시 조인 최적화가 설정되어 있는지 확인합니다. 자세한 방법은 병렬 쿼리 클러스터에 대한 해시 조인 설정 단원을 참조하십시오.

aurora_parallel_queryaurora_disable_hash_join과 같은 파라미터를 사용자 지정하려면 클러스터와 함께 사용하는 사용자 지정 파라미터 그룹이 있어야 합니다. DB 파라미터 그룹을 사용하여 각 DB 인스턴스에 대해 이러한 파라미터를 개별적으로 지정할 수 있습니다. 그러나 DB 클러스터 파라미터 그룹에서 지정하는 것이 좋습니다. 이렇게 하면 클러스터의 모든 DB 인스턴스가 이러한 파라미터에 대해 동일한 설정을 상속합니다.

제한 사항

다음 제한 사항이 병렬 쿼리 기능에 적용됩니다.

  • 병렬 쿼리는 Aurora I/O-Optimized DB 클러스터 스토리지 구성에서 지원되지 않습니다.

  • db.t2 또는 db.t3 인스턴스 클래스에는 병렬 쿼리를 사용할 수 없습니다. 이 제한은 aurora_pq_force 세션 변수를 사용하여 병렬 쿼리를 요청하는 경우에도 적용됩니다.

  • 병렬 쿼리는 COMPRESSED 또는 REDUNDANT 행 형식을 사용하는 테이블에는 적용되지 않습니다. 병렬 쿼리에 사용하려는 테이블에는 COMPACT 또는 DYNAMIC 행 형식을 사용합니다.

  • Aurora는 비용 기반 알고리즘을 사용하여 각 SQL 문에 대해 병렬 쿼리 메커니즘을 사용할지 여부를 결정합니다. 명령문에서 특정 SQL 구문을 사용하면 병렬 쿼리가 방지되거나 해당 명령문에 대해 병렬 쿼리가 실행되지 않을 수 있습니다. SQL 구문과 병렬 쿼리의 호환성에 대한 자세한 내용은 병렬 쿼리가 SQL 구조에서 작동하는 방법 단원을 참조하세요.

  • 각 Aurora DB 인스턴스는 한 번에 일정한 수의 병렬 쿼리 세션만 실행할 수 있습니다. 쿼리에 하위 쿼리, 조인 또는 UNION 연산자 같은 병렬 쿼리를 사용하는 여러 부분이 있는 경우, 그러한 단계가 순차적으로 실행됩니다. 구문은 한 시점에 단일 병렬 쿼리 세션으로만 계산됩니다. 병렬 쿼리 상태 변수를 사용하여 활성 세션의 수를 모니터링할 수 있습니다. 상태 변수 Aurora_pq_max_concurrent_requests를 쿼리하여 주어진 DB 인스턴스의 동시 세션에 대한 제한을 확인할 수 있습니다.

  • 병렬 쿼리는 Aurora가 지원되는 모든 AWS 리전에서 사용할 수 있습니다. 대부분의 AWS 리전에서 병렬 쿼리를 사용하는 데 필요한 최소 Aurora MySQL 버전은 2.09입니다.

  • 병렬 쿼리는 데이터 집약적인 쿼리의 성능을 향상하도록 설계되었습니다. 경량 쿼리용으로 설계되지 않았습니다.

  • SELECT 문, 특히 데이터 집약적인 문에는 리더 노드를 사용하는 것이 좋습니다.

병렬 쿼리를 사용할 경우 I/O 비용

Aurora MySQL 클러스터가 병렬 쿼리를 사용하는 경우 VolumeReadIOPS 값이 증가할 수 있습니다. 병렬 쿼리는 버퍼 풀을 사용하지 않습니다. 따라서 쿼리는 빠르지만 이렇게 최적화된 프로세싱은 읽기 작업 및 관련 비용을 증가시킬 수 있습니다.

쿼리에 대한 병렬 쿼리 I/O 비용은 스토리지 계층에서 측정되며 병렬 쿼리를 켠 상태에서 같거나 더 커집니다. 이를 통해 얻을 수 있는 이점은 쿼리 성능이 향상된다는 것입니다. 병렬 쿼리를 사용할 경우 I/O 비용이 높아질 수 있는 두 가지 이유가 있습니다.

  • 테이블의 일부 데이터가 버퍼 풀에 있더라도 병렬 쿼리는 스토리지 계층에서 모든 데이터를 스캔해야 하므로 I/O 비용이 발생합니다.

  • 병렬 쿼리를 실행해도 버퍼 풀이 워밍업되지 않습니다. 결과적으로 동일한 병렬 쿼리를 연속으로 실행하면 전체 I/O 비용이 발생합니다.

병렬 쿼리 클러스터 계획

병렬 쿼리가 설정된 DB 클러스터를 계획하려면 몇 가지 선택이 필요합니다. 여기에는 설정 단계(전체 Aurora MySQL 클러스터 생성 또는 복원)를 수행하고 DB 클러스터에서 병렬 쿼리를 설정할 범위를 결정하는 작업이 포함됩니다.

계획 과정에서 다음과 같은 사항을 고려해야 합니다.

  • MySQL 5.7과 호환되는 Aurora MySQL을 사용하는 경우 Aurora MySQL 2.09 이상을 선택해야 합니다. 이 경우 항상 프로비저닝된 클러스터를 생성합니다. 그런 다음 aurora_parallel_query 파라미터를 사용하여 병렬 쿼리를 설정합니다.

    버전 2.09 이상을 실행하는 기존 Aurora MySQL 클러스터가 있는 경우 병렬 쿼리를 사용하기 위해 새 클러스터를 생성할 필요가 없습니다. 클러스터 또는 클러스터의 특정 DB 인스턴스를 aurora_parallel_query 파라미터가 설정된 파라미터 그룹에 연결할 수 있습니다. 이렇게 하면 병렬 쿼리와 함께 사용할 관련 데이터를 설정하는 데 드는 시간과 노력을 줄일 수 있습니다.

  • 테이블에 액세스할 때 병렬 쿼리를 사용할 수 있도록 재구성해야 하는 대형 테이블이 있는지 확인하고 조치를 취합니다. 병렬 쿼리가 유용한 일부 대형 테이블의 경우 새 버전을 만들어야 할 수도 있습니다. 예를 들어 전체 텍스트 검색 인덱스를 제거해야 할 수 있습니다. 자세한 내용은 병렬 쿼리를 활용하기 위해 스키마 객체 생성 섹션을 참조하세요.

병렬 쿼리를 위한 Aurora MySQL 버전 호환성 확인

병렬 쿼리 클러스터와 호환되는 Aurora MySQL 버전을 확인하려면 describe-db-engine-versions AWS CLI 명령을 사용하고 SupportsParallelQuery 필드의 값을 확인합니다. 다음 코드 예제는 지정된 AWS 리전에서 병렬 쿼리 클러스터에 사용할 수 있는 조합을 확인하는 방법을 보여줍니다. 한 줄에 전체 --query 파라미터 문자열을 지정해야 합니다.

aws rds describe-db-engine-versions --region us-east-1 --engine aurora-mysql \ --query '*[]|[?SupportsParallelQuery == `true`].[EngineVersion]' --output text

위의 명령은 다음과 비슷한 출력을 생성합니다. 출력은 지정된 AWS 리전에서 사용 가능한 Aurora MySQL 버전에 따라 달라질 수 있습니다.

5.7.mysql_aurora.2.11.1 8.0.mysql_aurora.3.01.0 8.0.mysql_aurora.3.01.1 8.0.mysql_aurora.3.02.0 8.0.mysql_aurora.3.02.1 8.0.mysql_aurora.3.02.2 8.0.mysql_aurora.3.03.0

클러스터에서 병렬 쿼리를 사용하기 시작한 후 성능을 모니터링하고 병렬 쿼리 사용에 대한 장애 요소를 제거할 수 있습니다. 해당 지침은 병렬 쿼리를 위한 성능 튜닝 단원을 참조하십시오.

병렬 쿼리에서 작동하는 DB 클러스터 생성

병렬 쿼리를 사용하여 Aurora MySQL 클러스터를 생성하려면, 새 인스턴스를 추가하거나 다른 Aurora MySQL 클러스터에서 수행하는 것과 동일한 AWS Management Console 및 AWS CLI 기법을 사용하는 다른 관리 작업을 수행합니다. 병렬 쿼리에서 작동하는 새 클러스터를 생성할 수 있습니다. 또한 MySQL과 호환되는 Aurora DB 클러스터의 스냅샷에서 복원하여 병렬 쿼리에서 작동하는 DB 클러스터도 생성할 수 있습니다. 새 Aurora MySQL 클러스터를 생성하는 절차에 익숙하지 않은 경우, Amazon Aurora DB 클러스터 생성에서 배경 정보를 확인할 수 있습니다.

Aurora MySQL 엔진 버전을 선택할 때는 최신 버전을 선택하는 것이 좋습니다. 현재 Aurora MySQL 버전 2.09이상이 병렬 쿼리를 지원합니다. Aurora MySQL 2.09 이상을 사용하면 병렬 쿼리를 설정 및 해제하거나 기존 클러스터에서 병렬 쿼리를 사용할 수 있는 유연성이 높아집니다.

새 클러스터를 생성하든 스냅샷에서 복원하든, 새 DB 인스턴스를 추가하기 위해 다른 Aurora MySQL 클러스터에서 수행하는 것과 동일한 기법을 사용합니다.

콘솔을 사용하여 병렬 쿼리 클러스터 생성

다음 설명에 따라 콘솔을 사용하여 새 병렬 쿼리 클러스터를 생성할 수 있습니다.

AWS Management Console을 사용하여 병렬 쿼리 클러스터를 생성하려면
  1. AWS Management Console의 일반 Amazon Aurora DB 클러스터 생성 절차를 따르십시오.

  2. 엔진 선택 화면에서 Aurora MySQL을 선택합니다.

    엔진 버전에서 Aurora MySQL 2.09 이상을 선택합니다. 이러한 버전을 사용하면 병렬 쿼리 사용에 대한 제한이 가장 적어지며 언제든지 병렬 쿼리를 설정하거나 해제할 수 있는 유연성이 극대화됩니다.

    이 클러스터에 최신 Aurora MySQL 버전을 사용하는 것이 어려울 경우 병렬 쿼리 기능을 지원하는 버전 표시를 선택합니다. 이렇게 하면 버전 메뉴가 필터링되어 병렬 쿼리와 호환되는 특정 Aurora MySQL 버전만 표시됩니다.

  3. 추가 구성에서 DB 클러스터 파라미터 그룹에 대해 생성한 파라미터 그룹을 선택합니다. Aurora MySQL 2.09 이상에서는 이러한 사용자 지정 파라미터 그룹을 사용해야 합니다. DB 클러스터 파라미터 그룹에서 파라미터 설정 aurora_parallel_query=ONaurora_disable_hash_join=OFF를 지정합니다. 이렇게 하면 클러스터에 대한 병렬 쿼리가 설정되고 병렬 쿼리와 함께 작동하는 해시 조인 최적화가 설정됩니다.

새 클러스터가 병렬 쿼리를 사용할 수 있는지 확인하려면
  1. 앞에 나온 방법을 사용하여 클러스터를 생성합니다.

  2. (Aurora MySQL 버전 2 또는 3의 경우) aurora_parallel_query 구성 설정이 참인지 확인합니다.

    mysql> select @@aurora_parallel_query; +-------------------------+ | @@aurora_parallel_query | +-------------------------+ | 1 | +-------------------------+
  3. (Aurora MySQL 버전 2의 경우) aurora_disable_hash_join 설정이 거짓인지 확인합니다.

    mysql> select @@aurora_disable_hash_join; +----------------------------+ | @@aurora_disable_hash_join | +----------------------------+ | 0 | +----------------------------+
  4. 일부 대형 테이블과 데이터 집약적 쿼리의 경우 쿼리 계획을 검토하여 일부 쿼리에 병렬 쿼리 최적화가 사용되고 있는지 확인합니다. 이 작업을 수행하려면 의 절차를 수행합니다어떤 문이 병렬 쿼리를 사용하는지 확인

CLI를 사용하여 병렬 쿼리 클러스터 생성

다음 설명에 따라 CLI를 사용하여 새 병렬 쿼리 클러스터를 생성할 수 있습니다.

AWS CLI을 사용하여 병렬 쿼리 클러스터를 생성하려면
  1. (선택 사항) 병렬 쿼리 클러스터와 호환되는 Aurora MySQL 버전을 확인합니다. 이를 위해 describe-db-engine-versions 명령을 사용하고 SupportsParallelQuery 필드 값을 확인합니다. 관련 예제는 병렬 쿼리를 위한 Aurora MySQL 버전 호환성 확인 섹션을 참조하세요

  2. (선택 사항) aurora_parallel_query=ONaurora_disable_hash_join=OFF 설정으로 사용자 지정 DB 클러스터 파라미터 그룹을 생성합니다. 다음과 같은 명령을 사용합니다.

    aws rds create-db-cluster-parameter-group --db-parameter-group-family aurora-mysql5.7 --db-cluster-parameter-group-name pq-enabled-57-compatible aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name pq-enabled-57-compatible \ --parameters ParameterName=aurora_parallel_query,ParameterValue=ON,ApplyMethod=pending-reboot aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name pq-enabled-57-compatible \ --parameters ParameterName=aurora_disable_hash_join,ParameterValue=OFF,ApplyMethod=pending-reboot

    이 단계를 수행하는 경우 이후 --db-cluster-parameter-group-name my_cluster_parameter_group 문에서 create-db-cluster 옵션을 지정합니다. 고유한 해당 파라미터 그룹 이름으로 대치합니다. 이 단계를 생략하는 경우 병렬 쿼리 설정 및 해제에 설명된 대로 파라미터 그룹을 생성하고 나중에 클러스터에 연결합니다.

  3. AWS CLI의 일반 Amazon Aurora DB 클러스터 생성 절차를 따르십시오.

  4. 다음 옵션 세트를 지정하십시오.

    • --engine 옵션의 경우 aurora-mysql를 사용합니다. 이러한 값은 MySQL 5.7 또는 8.0과 호환되는 병렬 쿼리 클러스터를 생성합니다.

    • --db-cluster-parameter-group-name 옵션에 생성한 DB 클러스터 파라미터 그룹의 이름을 지정하고 파라미터 값 aurora_parallel_query=ON을 지정합니다. 이 옵션을 생략하는 경우 기본 파라미터 그룹을 사용하여 클러스터를 생성한 다음 나중에 해당 사용자 지정 파라미터 그룹을 사용하도록 수정할 수 있습니다.

    • --engine-version 옵션에 병렬 쿼리와 호환되는 Aurora MySQL 버전을 사용합니다. 필요한 경우 병렬 쿼리 클러스터 계획의 절차를 사용하여 버전 목록을 가져옵니다. 버전 2.09.0 이상을 사용하세요. 이러한 버전과 모든 상위 버전에는 병렬 쿼리 기능에 대한 상당한 개선 사항이 포함되어 있습니다.

      다음 코드 예제에서는 작업 방법을 보여줍니다. $CLUSTER_ID와 같은 각 환경 변수를 고유한 해당 값으로 대치합니다. 이 예제에서는 마스터 사용자 암호를 생성하고 이를 Secrets Manager에서 관리하는 --manage-master-user-password 옵션도 지정합니다. 자세한 내용은 Amazon Aurora 및 AWS Secrets Manager를 통한 암호 관리 섹션을 참조하세요. 또는 --master-password 옵션을 사용하여 암호를 직접 지정하고 관리할 수 있습니다.

      aws rds create-db-cluster --db-cluster-identifier $CLUSTER_ID \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.11.1 \ --master-username $MASTER_USER_ID --manage-master-user-password \ --db-cluster-parameter-group-name $CUSTOM_CLUSTER_PARAM_GROUP aws rds create-db-instance --db-instance-identifier ${INSTANCE_ID}-1 \ --engine same_value_as_in_create_cluster_command \ --db-cluster-identifier $CLUSTER_ID --db-instance-class $INSTANCE_CLASS
  5. 생성하거나 복원한 클러스터에서 병렬 쿼리 기능을 사용할 수 있는지 확인합니다.

    aurora_parallel_query 구성 설정이 존재하는지 확인합니다. 이 설정의 값이 1이면 병렬 쿼리를 사용할 수 있습니다. 이 설정의 값이 0이면 먼저 1로 설정해야 병렬 쿼리를 사용할 수 있습니다. 어느 경우이든 클러스터에서 병렬 쿼리를 수행할 수 있습니다.

    mysql> select @@aurora_parallel_query; +------------------------+ | @@aurora_parallel_query| +------------------------+ | 1 | +------------------------+
AWS CLI을 사용하여 스냅샷을 병렬 쿼리 클러스터에 복원하려면
  1. 병렬 쿼리 클러스터와 호환되는 Aurora MySQL 버전을 확인합니다. 이를 위해 describe-db-engine-versions 명령을 사용하고 SupportsParallelQuery 필드 값을 확인합니다. 관련 예제는 병렬 쿼리를 위한 Aurora MySQL 버전 호환성 확인 섹션을 참조하세요 복원된 클러스터에 사용할 버전을 결정합니다. MySQL 5.7과 호환되는 클러스터에 Aurora MySQL 2.09.0을 선택합니다.

  2. Aurora MySQL 호환 클러스터 스냅샷을 찾습니다.

  3. AWS CLI의 일반 DB 클러스터 스냅샷에서 복원 절차를 따르십시오.

    aws rds restore-db-cluster-from-snapshot \ --db-cluster-identifier mynewdbcluster \ --snapshot-identifier mydbclustersnapshot \ --engine aurora-mysql
  4. 생성하거나 복원한 클러스터에서 병렬 쿼리 기능을 사용할 수 있는지 확인합니다. CLI를 사용하여 병렬 쿼리 클러스터 생성에 나온 것과 동일한 확인 절차를 사용합니다.

병렬 쿼리 설정 및 해제

병렬 쿼리가 설정되면 Aurora MySQL이 각 쿼리의 런타임 시 병렬 쿼리를 사용할지 여부를 결정합니다. 조인, 통합, 하위 쿼리 등의 경우에는 Aurora MySQL이 각 쿼리 블록의 실행 시간에 병렬 쿼리를 사용할지 여부를 결정합니다. 자세한 내용은 어떤 문이 병렬 쿼리를 사용하는지 확인병렬 쿼리가 SQL 구조에서 작동하는 방법 단원을 참조하십시오.

aurora_parallel_query 옵션을 사용하여 DB 인스턴스에 대하여 전역 수준과 세션 수준에서 모두 동적으로 병렬 쿼리를 설정 및 해제할 수 있습니다. DB 클러스터 그룹의 aurora_parallel_query 설정을 변경하여 병렬 쿼리를 기본적으로 설정하거나 해제할 수 있습니다.

mysql> select @@aurora_parallel_query; +------------------------+ | @@aurora_parallel_query| +------------------------+ | 1 | +------------------------+

세션 수준에서 aurora_parallel_query 파라미터를 전환하려면 표준 방법을 사용하여 클라이언트 구성 설정을 변경합니다. 예를 들어 mysql 명령줄을 통해 또는 JDBC 또는 ODBC 애플리케이션 내에서 이렇게 할 수 있습니다. 표준 MySQL 클라이언트에서는 명령이 set session aurora_parallel_query = {'ON'/'OFF'}입니다. 또한 JDBC 구성 또는 애플리케이션 코드에 세션 수준 파라미터를 추가하여 동적으로 병렬 쿼리를 설정하거나 해제할 수 있습니다.

특정 DB 인스턴스 또는 전체 클러스터에 대해 aurora_parallel_query 파라미터 설정을 영구적으로 변경할 수 있습니다. DB 파라미터 그룹에서 파라미터 값을 지정하면 해당 값은 클러스터의 특정 DB 인스턴스에만 적용됩니다. DB 클러스터 파라미터 그룹에서 파라미터 값을 지정하면 클러스터의 모든 DB 인스턴스가 동일한 설정을 상속합니다. aurora_parallel_query 파라미터를 전환하려면 파라미터 그룹 작업에 설명된 대로 파라미터 그룹으로 작업하기 위한 기술을 사용합니다. 다음 단계를 따릅니다.

  1. 사용자 지정 클러스터 파라미터 그룹(권장) 또는 사용자 지정 DB 파라미터 그룹을 생성합니다.

  2. 이 파라미터 그룹에서 원하는 값으로 parallel_query를 업데이트합니다.

  3. DB 클러스터 파라미터 그룹을 생성했는지 아니면 DB 파라미터 그룹을 생성했는지에 따라 파라미터 그룹을 Aurora 클러스터에 연결하거나 병렬 쿼리 기능을 사용할 특정 DB 인스턴스에 연결합니다.

    작은 정보

    aurora_parallel_query는 동적 파라미터이므로 이 설정을 변경한 후에 클러스터를 다시 시작할 필요가 없습니다. 그러나 옵션을 토글하기 전에 병렬 쿼리를 사용하고 있던 모든 연결은 연결이 닫히거나 인스턴스가 재부팅될 때까지 계속됩니다.

ModifyDBClusterParameterGroup 또는 ModifyDBParameterGroup API 작업이나 AWS Management Console을 사용하여 병렬 쿼리 파라미터를 수정할 수 있습니다.

병렬 쿼리 클러스터에 대한 해시 조인 설정

병렬 쿼리는 해시 조인 최적화에서 이익을 얻는 리소스 집약적인 쿼리 유형에 일반적으로 사용됩니다. 따라서 병렬 쿼리를 사용하려는 클러스터에 대해 해시 조인을 설정하는 것이 좋습니다. 해시 조인을 효과적으로 사용하는 방법에 대한 자세한 내용은 해시 조인을 사용하여 대규모 Aurora MySQL 조인 쿼리 최적화 섹션을 참조하세요.

콘솔을 사용하여 병렬 쿼리 설정 및 해제

파라미터 그룹으로 작업하여 DB 인스턴스 수준 또는 DB 클러스터 수준에서 병렬 쿼리를 설정하거나 해제할 수 있습니다.

AWS Management Console을 사용하여 DB 클러스터에 대한 병렬 쿼리를 설정하거나 해제하려면
  1. 파라미터 그룹 작업에 설명된 대로 사용자 지정 파라미터 그룹을 생성합니다.

  2. aurora_parallel_query를 1(활성화됨) 또는 0(비활성화됨)으로 업데이트합니다. 병렬 쿼리 기능을 사용할 수 있는 클러스터에서는 aurora_parallel_query가 기본적으로 해제되어 있습니다.

  3. 사용자 지정 클러스터 파라미터 그룹을 사용하는 경우 병렬 쿼리 기능을 사용할 Aurora DB 클러스터에 해당 그룹을 연결합니다. 사용자 지정 DB 파라미터 그룹을 사용하는 경우 클러스터에 있는 하나 이상의 DB 인스턴스에 해당 그룹을 연결합니다. 클러스터 파라미터 그룹을 사용하는 것이 좋습니다. 이렇게 하면 클러스터의 모든 DB 인스턴스가 병렬 쿼리 및 해시 조인과 같은 관련 기능에 대해 동일한 설정을 갖게 됩니다.

CLI를 사용하여 병렬 쿼리 설정 및 해제

modify-db-cluster-parameter-group 또는 modify-db-parameter-group 명령을 사용하여 병렬 쿼리 파라미터를 수정할 수 있습니다. aurora_parallel_query의 값을 DB 클러스터 파라미터 그룹을 통해 지정하는지 아니면 DB 파라미터 그룹을 통해 지정하는지에 따라 적절한 명령을 선택합니다.

CLI를 사용하여 DB 클러스터에 대한 병렬 쿼리를 설정하거나 해제하려면
  • modify-db-cluster-parameter-group 명령을 사용하여 병렬 쿼리 파라미터를 수정합니다. 다음과 같은 명령을 사용합니다. 사용자 지정 파라미터 그룹의 해당 이름으로 대치합니다. ON 옵션의 OFF 부분을 ParameterValue 또는 --parameters로 대치합니다.

    $ aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name cluster_param_group_name \ --parameters ParameterName=aurora_parallel_query,ParameterValue=ON,ApplyMethod=pending-reboot { "DBClusterParameterGroupName": "cluster_param_group_name" } aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name cluster_param_group_name \ --parameters ParameterName=aurora_pq,ParameterValue=ON,ApplyMethod=pending-reboot

또한 세션 수준에서도(예를 들어 mysql 명령줄을 통해 혹은 JDBC 또는 ODBC 애플리케이션 내에서) 병렬 쿼리를 설정하거나 해제할 수 있습니다. 그렇게 하려면, 표준 메서드를 사용하여 클라이언트 구성 설정을 변경합니다. 예를 들어, 표준 MySQL 클라이언트에서는 Aurora MySQL의 경우 명령이 set session aurora_parallel_query = {'ON'/'OFF'}이고,

또한 JDBC 구성 또는 애플리케이션 코드에 세션 수준 파라미터를 추가하여 동적으로 병렬 쿼리를 설정하거나 해제할 수 있습니다.

병렬 쿼리 옵티마이저 재정의

aurora_pq_force 세션 변수를 사용하여 병렬 쿼리 옵티마이저 프로그램을 재정의하고 모든 쿼리에 대해 병렬 쿼리를 요청할 수 있습니다. 이 작업은 테스트 목적으로만 하는 것이 좋습니다. 다음 예제는 세션에서 aurora_pq_force를 사용하는 방법을 보여줍니다.

set SESSION aurora_parallel_query = ON; set SESSION aurora_pq_force = ON;

재정의를 해제하려면 다음을 수행합니다.

set SESSION aurora_pq_force = OFF;

병렬 쿼리를 위한 업그레이드 고려 사항

병렬 쿼리 클러스터를 업그레이드할 때 원래 버전과 대상 버전에 따라 병렬 쿼리가 최적화할 수 있는 쿼리 유형을 개선할 수 있습니다. 병렬 쿼리에 특수 엔진 모드 파라미터를 지정하지 않아도 될 수 있습니다. 다음 섹션에서는 병렬 쿼리가 설정된 클러스터를 업그레이드하는 경우 고려 사항에 대해 설명합니다.

Aurora MySQL 버전 3에 병렬 쿼리 클러스터 업그레이드

여러 SQL 문, 절 및 데이터 유형에는 Aurora MySQL 버전 3부터 새로운 병렬 쿼리 지원 또는 향상된 병렬 쿼리 지원이 있습니다. 버전 3 이전 릴리스에서 업그레이드하는 경우 추가 쿼리가 병렬 쿼리 최적화를 통해 이점을 얻을 수 있는지 확인합니다. 이러한 병렬 쿼리 개선 사항에 대한 자세한 내용은 열 데이터 유형, 분할된 테이블집계 함수, GROUP BY 절 및 HAVING 절 섹션을 참조하세요.

Aurora MySQL 2.08 이하에서 병렬 쿼리 클러스터를 업그레이드하는 경우 병렬 쿼리를 설정하는 방법의 변경 사항에 대해서도 알아봅니다. 이렇게 하려면 Aurora MySQL 2.09 이상으로 업그레이드 섹션을 참조하세요.

Aurora MySQL 버전 3에서 해시 조인 최적화는 기본적으로 설정되어 있습니다. 이전 버전의 aurora_disable_hash_join 구성 옵션은 사용되지 않습니다.

Aurora MySQL 2.09 이상으로 업그레이드

Aurora MySQL 버전 2.09 이상에서는 병렬 쿼리가 프로비저닝된 클러스터에 대해 작동하며 parallelquery 엔진 모드 파라미터가 필요하지 않습니다. 따라서 이러한 버전에서 병렬 쿼리를 사용하기 위해 새 클러스터를 생성하거나 기존 스냅샷에서 복원할 필요가 없습니다. Aurora MySQL DB 클러스터의 부 버전 또는 패치 수준 업그레이드에 설명된 업그레이드 절차를 사용하여 클러스터를 이러한 버전으로 업그레이드할 수 있습니다. 병렬 쿼리 클러스터인지 또는 프로비저닝된 클러스터인지에 관계없이 이전 클러스터를 업그레이드할 수 있습니다. 엔진 버전 메뉴에서 선택 항목 수를 줄이려면 병렬 쿼리 기능을 지원하는 버전 표시를 선택하여 해당 메뉴의 항목을 필터링할 수 있습니다. 그런 다음 Aurora MySQL 2.09 이상을 선택합니다.

이전 병렬 쿼리 클러스터를 Aurora MySQL 2.09 이상으로 업그레이드한 후 업그레이드된 클러스터에서 병렬 쿼리를 설정합니다. 이러한 버전에서는 병렬 쿼리가 기본적으로 해제되어 있으며 이를 활성화하는 절차가 다릅니다. 해시 조인 최적화도 기본적으로 해제되어 있으므로 별도로 설정해야 합니다. 따라서 업그레이드 후 이러한 설정을 다시 설정하도록 합니다. 관련 지침은 병렬 쿼리 설정 및 해제병렬 쿼리 클러스터에 대한 해시 조인 설정 단원을 참조하세요.

특히 aurora_parallel_query=ONaurora_disable_hash_join=OFF 대신 aurora_pq_supportedaurora_pq 구성 파라미터를 사용하여 병렬 쿼리를 설정합니다. aurora_pq_supportedaurora_pq 파라미터는 최신 Aurora MySQL 버전에서는 더 이상 사용되지 않습니다.

업그레이드된 클러스터에서 EngineMode 속성은 provisioned 대신 parallelquery 값을 갖습니다. 지정된 엔진 버전에 대해 병렬 쿼리를 사용할 수 있는지 여부를 확인하려면 이제 SupportsParallelQuery describe-db-engine-versions 명령의 출력에서 AWS CLI 필드 값을 확인합니다. 이전 Aurora MySQL 버전에서는 parallelquery 목록에 SupportedEngineModes가 있는지 확인했습니다.

Aurora MySQL 버전 2.09 이상으로 업그레이드한 후 다음 기능을 이용할 수 있습니다. 이러한 기능은 이전 Aurora MySQL 버전을 실행하는 병렬 쿼리 클러스터에는 사용할 수 없습니다.

병렬 쿼리를 위한 성능 튜닝

병렬 쿼리로 워크로드의 성능을 관리하려면, 이 최적화가 가장 도움이 되는 쿼리에 병렬 쿼리가 사용되어야 합니다.

그렇게 하기 위해 다음을 수행할 수 있습니다.

  • 최대 규모의 테이블이 병렬 쿼리와 호환되는지 확인합니다. 이러한 테이블에 대한 쿼리에 병렬 쿼리 최적화가 활용될 수 있도록 테이블 속성을 변경하거나 일부 테이블을 다시 생성할 수 있습니다. 자세한 방법은 병렬 쿼리를 활용하기 위해 스키마 객체 생성 단원을 참조하십시오.

  • 어떤 쿼리가 병렬 쿼리를 사용하는지 모니터링합니다. 자세한 방법은 병렬 쿼리 모니터링 단원을 참조하십시오.

  • 병렬 쿼리가 데이터 집약적인 장기 실행 쿼리에서 사용되는지 그리고 적절한 수준의 워크로드 동시성에서 사용되는지 확인합니다. 자세한 방법은 어떤 문이 병렬 쿼리를 사용하는지 확인 단원을 참조하십시오.

  • SQL 코드를 세부 조정하여 예상한 쿼리에 병렬 쿼리가 적용되도록 설정합니다. 자세한 방법은 병렬 쿼리가 SQL 구조에서 작동하는 방법 단원을 참조하십시오.

병렬 쿼리를 활용하기 위해 스키마 객체 생성

병렬 쿼리에 사용할 테이블을 생성하거나 수정하기 전에 필수 조건제한 사항에 설명된 요구 사항을 숙지해야 합니다.

병렬 쿼리는 테이블이 ROW_FORMAT=Compact 또는 ROW_FORMAT=Dynamic 설정을 사용해야 하기 때문에 Aurora 구성 설정에 INNODB_FILE_FORMAT 구성 옵션에 대한 변경 사항이 있는지 확인합니다. SHOW TABLE STATUS 문을 실행하여 데이터베이스의 모든 테이블에 대한 행 형식을 확인합니다.

스키마를 변경하여 병렬 쿼리가 더 많은 테이블에서 작동하도록 설정하기 전에 테스트해야 합니다. 테스트에서 병렬 쿼리로 인해 해당 테이블의 성능이 실제로 향상되는지 확인해야 합니다. 또한, 병렬 쿼리를 위한 스키마 요구 사항이 원하는 목표와 다른 식으로 양립될 수 있는지 확인합니다.

예를 들어, ROW_FORMAT=Compressed에서 ROW_FORMAT=Compact 또는 ROW_FORMAT=Dynamic으로 전환하기 전에 원본 테이블과 새 테이블에 대한 워크로드의 성능을 테스트합니다. 또한 데이터 볼륨 증가와 같은 다른 잠재적 영향도 고려합니다.

어떤 문이 병렬 쿼리를 사용하는지 확인

일반적인 작업에서는 병렬 쿼리를 이용하기 위해 어떤 특별한 조치를 수행할 필요가 없습니다. 쿼리가 병렬 쿼리를 위한 필수적 요구 사항을 충족한 후에는, 쿼리 옵티마이저가 각 특정 쿼리에 대하여 병렬 쿼리를 사용할지 여부를 자동으로 결정합니다.

개발 환경 또는 테스트 환경에서 실험을 실행하는 경우, 테이블에 행의 수 또는 전체 데이터 볼륨이 너무 작아서 병렬 쿼리가 사용되지 않을 수도 있습니다. 특히 실험을 수행하기 위해 최근에 만든 테이블의 경우, 테이블의 데이터가 버퍼 풀에서 전부 사용될 수도 있습니다.

클러스터 성능을 모니터링하거나 튜닝할 때, 병렬 쿼리가 적절한 컨텍스트에서 사용되고 있는지 여부를 확인해야 합니다. 이 기능을 활용하기 위해 데이터베이스 스키마, 설정, SQL 쿼리 또는 심지어 클러스터 토폴로지 및 애플리케이션 연결 설정을 조정할 수도 있습니다.

쿼리가 병렬 쿼리를 사용하고 있는지 확인하려면, EXPLAIN 문을 실행하여 쿼리 계획("실행 계획"이라고도 함)을 확인합니다. SQL 문, 절 및 표현식이 병렬 쿼리의 EXPLAIN 출력에 어떠한 영향을 미치는지에 대한 예는 병렬 쿼리가 SQL 구조에서 작동하는 방법를 참조하십시오.

다음 예제는 기존의 쿼리 계획과 병렬 쿼리 계획 간의 차이점을 보여줍니다. 이 설명 계획은 TPC-H 벤치마크의 쿼리 3에서 나온 것입니다. 이 단원의 곳곳에 나오는 샘플 쿼리의 대부분이 TPC-H 데이터 세트의 테이블을 사용합니다. TPC-H 웹 사이트에서 샘플 데이터를 생성하는 dbgen 프로그램, 테이블 정의 및 쿼리를 얻을 수 있습니다.

EXPLAIN SELECT l_orderkey, sum(l_extendedprice * (1 - l_discount)) AS revenue, o_orderdate, o_shippriority FROM customer, orders, lineitem WHERE c_mktsegment = 'AUTOMOBILE' AND c_custkey = o_custkey AND l_orderkey = o_orderkey AND o_orderdate < date '1995-03-13' AND l_shipdate > date '1995-03-13' GROUP BY l_orderkey, o_orderdate, o_shippriority ORDER BY revenue DESC, o_orderdate LIMIT 10;

기본적으로 쿼리에 다음과 같은 계획이 있을 수 있습니다. 쿼리 계획에 해시 조인이 사용된 것으로 표시되지 않으면 먼저 최적화가 설정되어 있는지 확인합니다.

+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+ | 1 | SIMPLE | customer | NULL | ALL | NULL | NULL | NULL | NULL | 1480234 | 10.00 | Using where; Using temporary; Using filesort | | 1 | SIMPLE | orders | NULL | ALL | NULL | NULL | NULL | NULL | 14875240 | 3.33 | Using where; Using join buffer (Block Nested Loop) | | 1 | SIMPLE | lineitem | NULL | ALL | NULL | NULL | NULL | NULL | 59270573 | 3.33 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+

Aurora MySQL 버전 3의 경우 다음 문을 실행하여 세션 수준에서 해시 조인을 설정합니다.

SET optimizer_switch='block_nested_loop=on';

Aurora MySQL 버전 2.09 이상에서는 aurora_disable_hash_join DB 파라미터 또는 DB 클러스터 파라미터를 0(비활성화됨)으로 설정합니다. aurora_disable_hash_join을 비활성화하면 optimizer_switch의 값이 hash_join=on이 됩니다.

해시 조인을 활성화한 후 EXPLAIN 문을 다시 실행해 보세요. 해시 조인을 효과적으로 사용하는 방법에 대한 자세한 내용은 해시 조인을 사용하여 대규모 Aurora MySQL 조인 쿼리 최적화 섹션을 참조하세요.

해시 조인이 설정되어 있지만 병렬 쿼리가 해제되어 있으면, 쿼리가 다음과 같은 계획(병렬 쿼리가 아니라 해시 조인을 사용)을 사용할 수 있습니다.

+----+-------------+----------+...+-----------+-----------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+-----------+-----------------------------------------------------------------+ | 1 | SIMPLE | customer |...| 5798330 | Using where; Using index; Using temporary; Using filesort | | 1 | SIMPLE | orders |...| 154545408 | Using where; Using join buffer (Hash Join Outer table orders) | | 1 | SIMPLE | lineitem |...| 606119300 | Using where; Using join buffer (Hash Join Outer table lineitem) | +----+-------------+----------+...+-----------+-----------------------------------------------------------------+

병렬 쿼리가 설정된 후에는 이 쿼리 계획의 두 단계가 Extra 출력의 EXPLAIN 열 아래에 표시된 대로 병렬 쿼리 최적화를 사용할 수 있습니다. 이 두 단계를 위한 I/O 집약적이고 CPU 집약적인 처리는 스토리지 계층으로 푸시 다운됩니다.

+----+...+--------------------------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+--------------------------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using index; Using temporary; Using filesort | | 1 |...| Using where; Using join buffer (Hash Join Outer table orders); Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra) | | 1 |...| Using where; Using join buffer (Hash Join Outer table lineitem); Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra) | +----+...+--------------------------------------------------------------------------------------------------------------------------------+

병렬 쿼리 및 병렬 쿼리가 적용될 수 있는 SQL 문의 부분에 대한 EXPLAIN 츨력을 해석하는 방법에 대한 내용은 병렬 쿼리가 SQL 구조에서 작동하는 방법을 참조하십시오.

다음 예제 출력은 콜드 버퍼 풀이 있는 db.r4.2xlarge 인스턴스에서 이전 쿼리를 실행한 결과를 보여줍니다. 병렬 쿼리 사용 시 쿼리가 상당히 더 빠르게 실행됩니다.

참고

타이밍은 많은 환경 요인에 의존하기 때문에 결과가 다를 수 있습니다. 본인의 고유한 환경, 워크로드 등에서의 결과를 확인하기 위해 항상 본인의 성능 테스트를 수행하십시오.

-- Without parallel query +------------+-------------+-------------+----------------+ | l_orderkey | revenue | o_orderdate | o_shippriority | +------------+-------------+-------------+----------------+ | 92511430 | 514726.4896 | 1995-03-06 | 0 | . . | 28840519 | 454748.2485 | 1995-03-08 | 0 | +------------+-------------+-------------+----------------+ 10 rows in set (24 min 49.99 sec)
-- With parallel query +------------+-------------+-------------+----------------+ | l_orderkey | revenue | o_orderdate | o_shippriority | +------------+-------------+-------------+----------------+ | 92511430 | 514726.4896 | 1995-03-06 | 0 | . . | 28840519 | 454748.2485 | 1995-03-08 | 0 | +------------+-------------+-------------+----------------+ 10 rows in set (1 min 49.91 sec)

이 단원의 곳곳에 나오는 샘플 쿼리의 대부분은 이 TPC-H 데이터 세트의 테이블을 사용합니다(특히, 2천만 개의 행과 다음 정의가 포함된 PART 테이블).

+---------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+---------------+------+-----+---------+-------+ | p_partkey | int(11) | NO | PRI | NULL | | | p_name | varchar(55) | NO | | NULL | | | p_mfgr | char(25) | NO | | NULL | | | p_brand | char(10) | NO | | NULL | | | p_type | varchar(25) | NO | | NULL | | | p_size | int(11) | NO | | NULL | | | p_container | char(10) | NO | | NULL | | | p_retailprice | decimal(15,2) | NO | | NULL | | | p_comment | varchar(23) | NO | | NULL | | +---------------+---------------+------+-----+---------+-------+

개별 SQL 문이 병렬 쿼리를 활용할 수 있는지 가늠하기 위해 본인의 워크로드로 시험하십시오. 그런 다음, 시간이 지남에 따라 실제 워크로드에서 병렬 쿼리가 얼마나 자주 사용되는지 확인할 수 있도록 다음 모니터링 기법을 사용합니다. 실제 워크로드의 경우, 동시성 한도와 같은 추가 요인이 적용됩니다.

병렬 쿼리 모니터링

Aurora MySQL 클러스터가 병렬 쿼리를 사용하는 경우 VolumeReadIOPS 값이 증가할 수 있습니다. 병렬 쿼리는 버퍼 풀을 사용하지 않습니다. 따라서 쿼리는 빠르지만 이렇게 최적화된 프로세싱은 읽기 작업 및 관련 비용을 증가시킬 수 있습니다.

Amazon RDS 콘솔에서 지표 보기에 설명된 Amazon CloudWatch 지표 외에도 Aurora는 다른 전역적 상태 변수를 제공합니다. 이러한 전역 상태 변수를 사용하여 병렬 쿼리 실행을 모니터링할 수 있습니다. 이를 통해 최적화 프로그램이 주어진 상황에서 병렬 쿼리를 사용하거나 사용하지 않는 이유를 파악할 수 있습니다. 이러한 변수에 액세스하기 위해 SHOW GLOBAL STATUS 명령을 사용할 수 있습니다. 또한 아래에 나열된 변수도 찾을 수 있습니다.

병렬 쿼리 세션은 데이터베이스에서 수행한 쿼리와 반드시 일대일 매핑되는 것은 아닙니다. 예를 들어, 쿼리 계획에 병렬 쿼리를 사용하는 두 단계가 있다고 가정해 봅시다. 이 경우에, 쿼리는 두 병렬 세션 및 시도된 요청을 위한 카운터가 필요하고 성공한 요청은 2씩 증가합니다.

EXPLAIN 문을 실행하여 병렬 쿼리로 시험할 때, 쿼리가 실제로 실행 중이지 않은 경우에도 "선택되지 않음"으로 지정된 카운터에서 증가가 있을 것으로 예상합니다. 프로덕션에서 병렬 쿼리로 작업할 때 "선택되지 않은" 카운터가 예상보다 더 빠르게 증가하고 있는지 확인할 수 있습니다. 이때 예상한 쿼리에 대해 병렬 쿼리가 실행되도록 조정할 수 있습니다. 이렇게 하려면 클러스터 설정, 쿼리 조합, 병렬 쿼리가 설정된 DB 인스턴스 등을 변경할 수 있습니다.

이러한 카운터는 DB 인스턴스 수준에서 추적됩니다. 서로 다른 엔드포인트에 연결된 경우, 각 DB 인스턴스가 자체의 고유한 병렬 쿼리 집합을 실행하기 때문에 서로 다른 지표가 표시될 수도 있습니다. 또한 리더 엔드포인트가 각 세션마다 서로 다른 DB 인스턴스에 연결된 경우에도 서로 다른 지표가 표시될 수 있습니다.

이름 설명

Aurora_pq_bytes_returned

병렬 쿼리 동안 헤드 노드에 전송된 튜플 데이터 구조를 위한 바이트 수입니다. Aurora_pq_pages_pushed_down과 비교하기 위해 16,384로 나눕니다.

Aurora_pq_max_concurrent_requests

이 Aurora DB 인스턴스에서 동시에 실행될 수 있는 병렬 쿼리 세션의 최대 수입니다. 이 수는 AWS DB 인스턴스 클래스에 따라 결정되는 고정된 수입니다.

Aurora_pq_pages_pushed_down

병렬 쿼리가 헤드 노드로 네트워크 전송을 회피한 데이터 페이지의 수입니다(각각 16 KiB의 고정 크기).

Aurora_pq_request_attempted

요청된 병렬 쿼리 세션의 수입니다. 이 값은 하위 쿼리 및 조인과 같은 SQL 구조에 따라, 쿼리 당 두 개 이상의 세션을 나타낼 수 있습니다.

Aurora_pq_request_executed

병렬 쿼리 세션의 수가 성공적으로 실행됩니다.

Aurora_pq_request_failed

클라이언트에 오류를 반환한 병렬 쿼리 세션의 수입니다. 일부 경우에 병렬 쿼리를 위한 요청이 실패할 수도 있습니다(예를 들어, 스토리지 계층의 문제로 인해). 이러한 경우에는 실패한 쿼리 부분이 비병렬 쿼리 메커니즘을 사용하여 다시 시도됩니다. 다시 시도된 쿼리 또한 실패하는 경우, 오류가 클라이언트에 반환되고 이 카운터가 증가합니다.

Aurora_pq_request_in_progress

병렬 쿼리 세션의 수가 현재 진행 중입니다. 이 수는 전체 Aurora DB 클러스터가 아니라 연결되어 있는 특정 Aurora DB 인스턴스에 적용됩니다. DB 인스턴스가 동시성 한도에 근접했는지 확인하려면, 이 값을 Aurora_pq_max_concurrent_requests와 비교합니다.

Aurora_pq_request_not_chosen

병렬 쿼리가 쿼리를 충족시키기 위해 선택되지 않은 횟수입니다. 이 값은 여러 개의 다른 더 세분화된 카운터의 합계입니다. 쿼리가 실제로 수행되지 않더라도 EXPLAIN 문을 통해 이 카운터가 증가할 수 있습니다.

Aurora_pq_request_not_chosen_below_min_rows

테이블에 있는 행의 수로 인해 병렬 쿼리가 선택되지 않은 횟수입니다. 쿼리가 실제로 수행되지 않더라도 EXPLAIN 문을 통해 이 카운터가 증가할 수 있습니다.

Aurora_pq_request_not_chosen_column_bit

예상 열 목록에서 지원되지 않는 데이터 형식으로 인해 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_column_geometry

테이블에 GEOMETRY 데이터 형식의 열이 있기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다. 이 제한 사항이 적용되지 않는 Aurora MySQL 버전에 대한 자세한 정보는 Aurora MySQL 버전 3에 병렬 쿼리 클러스터 업그레이드 섹션을 참조하세요.

Aurora_pq_request_not_chosen_column_lob

테이블에 LOB 데이터 형식의 열이 있거나 VARCHAR 선언된 길이로 인해 외부에 저장된 열이 있으므로에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다. 이 제한 사항이 제거된 Aurora MySQL 버전에 대한 자세한 정보는 Aurora MySQL 버전 3에 병렬 쿼리 클러스터 업그레이드 섹션을 참조하세요.

Aurora_pq_request_not_chosen_column_virtual

테이블에 가상 열이 포함되어 있기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_custom_charset

테이블에 사용자 지정 문자 집합이 있는 열이 있기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_fast_ddl

테이블이 현재 빠른 DDL ALTER 문에 의해 변경되고 있기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_few_pages_outside_buffer_pool

테이블 데이터 중 95% 미만이 버퍼 풀에 있는 경우에도, 버퍼링되지 않은 테이블 데이터가 병렬 쿼리가 가치 있을 만큼 충분하지 않았기 때문에 병렬 쿼리가 선택되지 않은 횟수입니다.

Aurora_pq_request_not_chosen_full_text_index

테이블에 전체 텍스트 인덱스가 있기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_high_buffer_pool_pct

테이블 데이터 중 많은 양이(현재, 95% 이상) 이미 버퍼 풀에 있었기 때문에 병렬 쿼리가 선택되지 않은 횟수입니다. 이러한 경우, 옵티마이저는 버퍼 풀에서 데이터 읽기가 더 효율적이라고 결정합니다. 쿼리가 실제로 수행되지 않더라도 EXPLAIN 문을 통해 이 카운터가 증가할 수 있습니다.

Aurora_pq_request_not_chosen_index_hint

쿼리에 인덱스 힌트가 포함되어 있기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_innodb_table_format

테이블이 지원되지 않는 InnoDB 행 형식을 사용하기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다. Aurora 병렬 쿼리는 COMPACT, REDUNDANTDYNAMIC 행 형식에만 적용됩니다.

Aurora_pq_request_not_chosen_long_trx

장기 실행 트랜잭션 내부에서 쿼리가 시작되는 중이어서 비병렬 쿼리 처리 경로를 사용한 병렬 쿼리 요청의 수입니다. 쿼리가 실제로 수행되지 않더라도 EXPLAIN 문을 통해 이 카운터가 증가할 수 있습니다.

Aurora_pq_request_not_chosen_no_where_clause

쿼리에 WHERE 절이 포함되어 있지 않기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_range_scan

쿼리가 인덱스에서 범위 스캔을 사용하기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_row_length_too_long

모든 열의 총 결합 길이가 너무 길기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_small_table

행의 수 및 평균 행 길이에 따라 결정된 테이블의 전체 크기로 인해 병렬 쿼리가 선택되지 않은 횟수입니다. 쿼리가 실제로 수행되지 않더라도 EXPLAIN 문을 통해 이 카운터가 증가할 수 있습니다.

Aurora_pq_request_not_chosen_temporary_table

쿼리가 지원되지 않는 MyISAM 또는 memory 테이블 형식을 사용하는 임시 테이블을 참조하기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_tx_isolation

쿼리가 지원되지 않는 트랜잭션 격리 수준을 사용하기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다. 읽기 전용 DB 인스턴스에서는 병렬 쿼리가 REPEATABLE READREAD COMMITTED 격리 수준에만 적용됩니다.

Aurora_pq_request_not_chosen_update_delete_stmts

쿼리가 UPDATE 또는 DELETE 문의 일부이기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다.

Aurora_pq_request_not_chosen_unsupported_access

WHERE 절이 병렬 쿼리를 위한 기준에 부합되지 않기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청의 수입니다. 이 결과는 쿼리에 데이터 집약적인 스캔이 필요하지 않은 경우이거나 쿼리가 DELETE 또는 UPDATE 문인 경우에 발생할 수 있습니다.

Aurora_pq_request_not_chosen_unsupported_storage_type

Aurora MySQL DB 클러스터가 지원되는 Aurora 클러스터 스토리지 구성을 사용하지 않기 때문에 비병렬 쿼리 처리 경로를 사용하는 병렬 쿼리 요청 수입니다. 이 파라미터는 Aurora MySQL 버전 3.04 이상에서 사용할 수 있습니다. 자세한 내용은 제한 사항 섹션을 참조하세요.

Aurora_pq_request_throttled

동시 병렬 쿼리의 최대 수가 이미 특정 Aurora DB 인스턴스에서 실행 중이기 때문에 병렬 쿼리가 선택되지 않은 횟수입니다.

병렬 쿼리가 SQL 구조에서 작동하는 방법

다음 단원에서는 특정 SQL 문이 병렬 쿼리를 사용하거나 사용하지 않는 이유와 Aurora MySQL 기능이 병렬 쿼리와 상호 작용하는 방법에 대한 자세한 내용을 확인할 수 있습니다. 이러한 정보는 병렬 쿼리를 사용하는 클러스터의 성능 문제를 진단하고 병렬 쿼리가 특정 워크로드에 적용되는 방법을 이해하는 데 도움이 될 수 있습니다.

병렬 쿼리를 사용하려는 결정은 문이 실행되는 시점에 발생하는 여러 요인에 의존합니다. 따라서 병렬 쿼리는 특정 쿼리를 위해 항상 사용되거나 절대 사용되지 않거나 특정 조건에서만 사용될 수 있습니다.

작은 정보

HTML에서 이러한 예제를 볼 때 각 코드 목록의 오른쪽 위에 있는 복사 위젯을 사용해 SQL 코드를 복사하여 직접 시도할 수 있습니다. 복사 위젯을 사용하면 mysql> 프롬프트 및 -> 연속 줄 주위에 추가 문자가 복사되지 않습니다.

EXPLAIN 문

이 섹션의 곳곳에 나오는 예제에서 보듯이, EXPLAIN 문은 쿼리의 각 단계가 병렬 쿼리를 위해 현재 적격한지 여부를 나타냅니다. 또한 쿼리의 어떤 부분이 스토리지 계층으로 푸시 다운될 수 있는지를 나타냅니다. 다음은 쿼리 계획에서 가장 중요한 항목입니다.

  • NULL 열의 key 외에 다른 값은 쿼리가 인덱스 조회를 사용하여 효율적으로 수행될 수 있어서 병렬 쿼리가 사용될 가능성이 낮음을 암시합니다.

  • rows 열의 작은 값(즉, 값이 수백만이 아님)은 쿼리가 병렬 쿼리가 가치 있을 만큼 충분한 데이터에 액세스하고 있지 않음을 암시합니다. 즉, 병렬 쿼리가 발생할 가능성이 낮습니다.

  • Extra 열은 병렬 쿼리가 사용될 것으로 예상되는 경우를 표시합니다. 이 출력은 다음 예제와 비슷합니다.

    Using parallel query (A columns, B filters, C exprs; D extra)

    columns 수는 쿼리 블록에서 조회되는 열의 수를 나타냅니다.

    filters 수는 상수에 대한 열 값의 단순 비교를 나타내는 WHERE 조건자의 수를 나타냅니다. 등식, 부등식 또는 범위에 대해 비교할 수 있습니다. Aurora는 이러한 종류의 조건자를 가장 효율적으로 병렬화할 수 있습니다.

    exprs 수는 함수 호출, 연산자, 또는 필터 조건만큼 효율적이지는 않지만 병렬화될 수 있는 다른 표현식 등과 같은 표현식의 수를 나타냅니다.

    extra 수는 푸시 다운될 수 없고 헤드 노드에 의해 수행되는 표현식의 수를 나타냅니다.

예를 들어, 다음 EXPLAIN 출력을 고려해 보십시오.

mysql> explain select p_name, p_mfgr from part -> where p_brand is not null -> and upper(p_type) is not null -> and round(p_retailprice) is not null; +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+

Extra 열의 정보는 쿼리 조건을 평가하고 결과 집합을 구성하기 위해 5개의 열이 각 행으로부터 추출되는 것을 보여줍니다. 한 개의 WHERE 조건자는 필터(즉, WHERE 절에서 직접 테스트되는 열)를 포함합니다. 두 WHERE 절은 더 복잡한 표현식(이 경우에는 함수 호출 포함)의 평가가 필요합니다. 0 extra 필드는 WHERE 절의 모든 작업이 병렬 쿼리 처리의 부분으로 스토리지 계층으로 푸시 다운됨을 확인합니다.

병렬 쿼리가 선택되지 않은 경우에는, 일반적으로 EXPLAIN 출력의 다른 열에서 이유를 추론할 수 있습니다. 예를 들어, rows 값이 너무 작을 수 있거나 possible_keys 열은 쿼리가 데이터 집약적인 스캔 대신 인덱스 조회를 사용할 수 있음을 나타낼 수 있습니다. 다음 예제에서는 쿼리가 적은 수의 행만 스캔할 것이라고 최적화 프로그램에서 추정할 수 있는 쿼리를 보여줍니다. 이는 기본 키의 특성을 기반으로 합니다. 이 경우에는 병렬 쿼리가 필요하지 않습니다.

mysql> explain select count(*) from part where p_partkey between 1 and 100; +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | 1 | SIMPLE | part | range | PRIMARY | PRIMARY | 4 | NULL | 99 | Using where; Using index | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+

병렬 쿼리의 사용 여부를 보여주는 출력은 EXPLAIN 문이 실행되는 시점에 사용할 수 있는 모든 요인을 고려합니다. 그 동안에 상황이 변경된 경우, 옵티마이저는 쿼리가 실제로 실행될 때 다른 선택을 할 수도 있습니다. 예를 들어, EXPLAIN은 문이 병렬 쿼리를 사용할 것이라고 보고할 수 있습니다. 그러나 나중에 쿼리가 실제로 실행될 때에는, 그 당시 조건을 기반으로 병렬 쿼리를 사용하지 않을 수도 있습니다. 그러한 조건에는 여러 다른 병렬 쿼리가 동시에 실행 중, 행이 테이블에서 삭제되는 중, 새 인덱스가 생성되는 중, 열린 트랜잭션 내에서 너무 많은 시간 경과 등이 포함될 수 있습니다.

WHERE 절

쿼리가 병렬 쿼리 최적화를 사용하기 위해서는 반드시 WHERE 절을 포함해야 합니다.

병렬 쿼리 최적화는 WHERE 절에 사용되는 다양한 유형의 표현식 속도를 높입니다.

  • 상수에 대한 열 값의 단순 비교(필터라고 알려짐). 이러한 비교는 스토리지 계층으로 푸시 다운되는 경우에 가장 많은 이점이 있습니다. 쿼리에 있는 필터 표현식의 수가 EXPLAIN 출력에 보고됩니다.

  • WHERE 절에 있는 다른 유형의 표현식 또한 가능한 경우 스토리지 계층으로 푸시 다운됩니다. 쿼리에 있는 그러한 표현식의 수가 EXPLAIN 출력에 보고됩니다. 이러한 표현식은 함수 호출, LIKE 연산자, CASE 표현식 등이 해당될 수 있습니다.

  • 특정 함수 및 연산자는 현재 병렬 쿼리에 의해 푸시 다운되지 않습니다. 쿼리에 있는 그러한 표현식의 수는 extra 출력에서 EXPLAIN 카운터로 보고됩니다. 나머지 쿼리도 여전히 병렬 쿼리를 사용할 수 있습니다.

  • 선택 목록의 표현식이 푸시 다운되지 않은 동안, 그러한 함수를 포함한 쿼리는 병렬 쿼리의 중간 결과를 위한 네트워크 트래픽 감소로부터 여전히 이점을 얻을 수 있습니다. 예를 들어, 선택 목록의 집계 함수를 호출하는 쿼리는 집계 함수가 푸시 다운되지 않는 경우에도 병렬 쿼리로부터 이점을 얻을 수 있습니다.

예를 들어, 다음 쿼리는 전체 테이블 스캔을 수행하고 P_BRAND 열의 모든 값을 처리합니다. 하지만, 쿼리가 WHERE 절을 하나도 포함하고 있지 않기 때문에 병렬 쿼리를 사용하지 않습니다.

mysql> explain select count(*), p_brand from part group by p_brand; +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | 1 | SIMPLE | part | ALL | NULL | NULL | NULL | NULL | 20427936 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+

반면에, 다음 쿼리는 결과를 필터링하는 WHERE 조건자를 포함하고 있으므로 병렬 쿼리가 적용될 수 있습니다.

mysql> explain select count(*), p_brand from part where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 -> group by p_brand; +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using temporary; Using filesort; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+...+----------+-------------------------------------------------------------------------------------------------------------+

옵티마이저가 쿼리 블록에 대해 반환되는 행의 수가 적다고 예상하는 경우, 병렬 쿼리가 해당 쿼리 블록에 사용되지 않습니다. 다음은 기본 키 열의 "~보다 큼" 연산자가 수백만의 행에 적용되고, 그로 인해 병렬 쿼리가 사용되는 사례를 보여주는 예제입니다. 정반대의 "~보다 작음" 테스트는 소수의 행에만 적용될 것으로 예상되므로 병렬 쿼리를 사용하지 않습니다.

mysql> explain select count(*) from part where p_partkey > 10; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+ mysql> explain select count(*) from part where p_partkey < 10; +----+...+------+--------------------------+ | id |...| rows | Extra | +----+...+------+--------------------------+ | 1 |...| 9 | Using where; Using index | +----+...+------+--------------------------+

데이터 정의 언어(DDL)

Aurora MySQL 버전 2에서 병렬 쿼리는 대기 중인 빠른 데이터 정의 언어(DDL) 작업이 없는 테이블에서만 사용할 수 있습니다. Aurora MySQL 버전 3에서는 인스턴트 DDL 작업과 동시에 테이블의 병렬 쿼리를 사용할 수 있습니다.

Aurora MySQL 버전 3의 인스턴트 DDL은 Aurora MySQL 버전 2의 빠른 DDL 기능을 대체합니다. 인스턴트 DDL에 대한 자세한 내용은 인스턴트 DDL(Aurora MySQL 버전 3) 섹션을 참조하세요.

열 데이터 유형

Aurora MySQL 버전 3에서 병렬 쿼리는 TEXT, BLOB, JSONGEOMETRY 데이터 유형이 있는 열을 포함하는 테이블에서 작업할 수 있습니다. 또한 선언된 최대 길이가 768바이트보다 긴 VARCHARCHAR 열에서 작업할 수 있습니다. 쿼리가 이처럼 대형 객체 유형을 포함하는 모든 열을 참조하는 경우 추가로 검색 작업을 수행하면 쿼리 처리에 일부 오버헤드가 추가됩니다. 이 경우 쿼리가 해당 열에 대한 참조를 생략할 수 있는지 확인합니다. 그렇지 않은 경우 벤치마크를 실행하여 병렬 쿼리가 설정되거나 해제된 상태에서 이러한 쿼리가 더 빠르게 수행되는지 확인합니다.

Aurora MySQL 버전 2에는 대형 객체 유형에 대해 병렬 쿼리에 다음과 같은 제한이 있습니다.

  • TEXT, BLOB, JSONGEOMETRY 데이터 유형은 병렬 쿼리에서 지원되지 않습니다. 이러한 유형의 열을 참조하는 쿼리는 병렬 쿼리를 사용할 수 없습니다.

  • 가변 길이 열(VARCHARCHAR 데이터 유형)은 768바이트의 최대 선언된 길이까지 병렬 쿼리와 호환됩니다. 더 긴 최대 길이로 선언된 유형의 열을 참조하는 쿼리는 병렬 쿼리를 사용할 수 없습니다. 멀티바이트 문자 집합을 사용하는 열의 경우, 바이트 제한이 문자 집합의 최대 바이트 수를 고려합니다. 예를 들어, utf8mb4 문자 집합(최대 문자 길이 = 4바이트)의 경우 VARCHAR(192) 열은 병렬 쿼리와 호환되지만 VARCHAR(193) 열은 호환되지 않습니다.

분할된 테이블

Aurora MySQL 버전 3에서 병렬 쿼리에서 파티션된 테이블을 사용할 수 있습니다. 파티션된 테이블은 내부적으로 여러 개의 작은 테이블로 표시되므로 파티션되지 않은 테이블에서 병렬 쿼리를 사용하는 쿼리는 동일하게 파티션된 테이블에서 병렬 쿼리를 사용할 수 없습니다. Aurora MySQL은 전체 테이블의 크기를 평가하는 대신 각 파티션이 병렬 쿼리 최적화에 적합할 만큼 충분히 큰지 여부를 고려합니다. 파티션된 테이블의 쿼리가 예상될 때 병렬 쿼리를 사용하지 않는 경우 Aurora_pq_request_not_chosen_small_table 상태 변수가 증가하는지 여부를 확인합니다.

예를 들어 한 테이블을 PARTITION BY HASH (column) PARTITIONS 2로 파티션하고 다른 테이블을 PARTITION BY HASH (column) PARTITIONS 10으로 파티션하는 것을 고려합니다. 두 개의 파티션이 있는 테이블의 파티션은 10개의 파티션이 있는 테이블보다 5배 더 큽니다. 따라서 병렬 쿼리는 파티션이 적은 테이블에 대한 쿼리에 사용될 가능성이 높습니다. 다음 예에서는 테이블 PART_BIG_PARTITIONS에는 두 개의 파티션이 있으며 PART_SMALL_PARTITIONS는 10개의 파티션이 있습니다. 동일한 데이터를 사용하면 병렬 쿼리는 큰 파티션이 적은 테이블에 사용될 가능성이 높습니다.

mysql> explain select count(*), p_brand from part_big_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | 1 | SIMPLE | part_big_partitions | p0,p1 | Using where; Using temporary; Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra; 1 group-bys, 1 aggrs) | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ mysql> explain select count(*), p_brand from part_small_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+-----------------------+-------------------------------+------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+-----------------------+-------------------------------+------------------------------+ | 1 | SIMPLE | part_small_partitions | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | Using where; Using temporary | +----+-------------+-----------------------+-------------------------------+------------------------------+

집계 함수, GROUP BY 절 및 HAVING 절

집계 함수를 포함하는 쿼리는 대용량 테이블 내에 많은 수의 행 스캔이 필요하기 때문에, 대개 병렬 쿼리를 위한 좋은 후보가 됩니다.

Aurora MySQL 3에서 병렬 쿼리는 선택 목록 및 HAVING 절에서 집계 함수 호출을 최적화할 수 있습니다.

Aurora MySQL 3 이전에서 선택 목록 또는 HAVING 절에 있는 집계 함수 호출은 스토리지 계층으로 푸시 다운되지 않습니다. 하지만, 병렬 쿼리는 집계 함수에서도 그러한 쿼리의 성능을 여전히 향상시킬 수 있습니다. 그렇게 하기 위해서 먼저 스토리지 계층에서 병렬적으로 원시 데이터 페이지로부터 열 값을 추출합니다. 그런 다음 이러한 값을 전체 데이터 페이지가 아니라 간소화된 튜플 형식으로 다시 헤드 노드로 전송합니다. 항상 그렇듯이, 쿼리는 병렬 쿼리를 위해 최소 하나 이상의 WHERE조건자가 활성화되어야 합니다.

다음은 병렬 쿼리로부터 이점을 얻을 수 있는 집계 쿼리의 유형을 보여주는 간단한 예제입니다. 중간 결과를 간소화된 형식으로 헤드 노드에 반환하거나, 중간 결과에서 일치하지 않는 행을 필터링하거나, 혹은 둘 다를 사용함으로써 이점을 얻습니다.

mysql> explain select sql_no_cache count(distinct p_brand) from part where p_mfgr = 'Manufacturer#5'; +----+...+----------------------------------------------------------------------------+ | id |...| Extra | +----+...+----------------------------------------------------------------------------+ | 1 |...| Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------------------------------------------------------------------------+ mysql> explain select sql_no_cache p_mfgr from part where p_retailprice > 1000 group by p_mfgr having count(*) > 100; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (3 columns, 0 filters, 1 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

WHERE 절의 함수 호출

Aurora는 병렬 쿼리 최적화를 WHERE 절의 대부분 내장 함수에 대한 호출에 적용할 수 있습니다. 이러한 함수 호출의 병렬화는 헤드 노드에서 일부 CPU 작업을 오프로드합니다. 가장 빠른 쿼리 단계 동안 조건자 함수를 병렬적으로 평가하면 Aurora가 전송되어 이후 단계에서 처리되는 데이터의 양을 최소화하는데 도움이 됩니다.

현재, 병렬화는 선택 목록의 함수 호출에 적용되지 않습니다. 이러한 함수는 동일한 함수 호출이 WHERE 절에 나타날지라도 헤드 노드에 의해 평가됩니다. 관련 열의 원래 값은 스토리지 노드에서 다시 헤드 노드로 전송되는 튜플에 포함되어 있습니다. 헤드 노드는 결과 집합의 최종 값을 생성하기 위해 UPPER, CONCATENATE 등과 같은 변환을 수행합니다.

다음 예제에서는, LOWER에 대한 호출이 WHERE 절에 나타나기 때문에 병렬 쿼리가 이 호출을 병렬화합니다. SUBSTRUPPER에 대한 호출이 선택 목록에 나타나기 때문에 병렬 쿼리가 이러한 호출에 영향을 주지 않습니다.

mysql> explain select sql_no_cache distinct substr(upper(p_name),1,5) from part -> where lower(p_name) like '%cornflower%' or lower(p_name) like '%goldenrod%'; +----+...+---------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+---------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+...+---------------------------------------------------------------------------------------------+

동일한 고려 사항이 CASE 표현식 또는 LIKE 연산자와 같은 다른 표현식에 적용됩니다. 예를 들어, 다음 예제에서는 병렬 쿼리가 CASE 절의 LIKE 표현식 및 WHERE 연산자를 평가하는 것을 보여줍니다.

mysql> explain select p_mfgr, p_retailprice from part -> where p_retailprice > case p_mfgr -> when 'Manufacturer#1' then 1000 -> when 'Manufacturer#2' then 1200 -> else 950 -> end -> and p_name like '%vanilla%' -> group by p_retailprice; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (4 columns, 0 filters, 2 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

LIMIT 절

현재, 병렬 쿼리는 LIMIT 절을 포함하는 쿼리 블록에는 사용되지 않습니다. 병렬 쿼리는 GROUP by, ORDER BY 또는 조인이 포함된 이전 쿼리 단계에 여전히 사용될 수 있습니다.

비교 연산자

옵티마이저는 비교 연산자를 평가하기 위해 스캔해야 하는 행의 수를 추산하고, 그 추산을 기반으로 병렬 쿼리를 사용할지 여부를 결정합니다.

아래에 첫 번째 예제는 기본 키 열에 대한 "같음" 비교가 병렬 쿼리 없이도 효율적으로 수행될 수 있음을 보여줍니다. 아래에 두 번째 예제는 인덱싱되지 않은 열에 대한 "더 작음" 비교에 수백만 개 행의 스캔이 필요하며 따라서 병렬 쿼리로부터 이점을 얻을 수 있음을 보여줍니다.

mysql> explain select * from part where p_partkey = 10; +----+...+------+-------+ | id |...| rows | Extra | +----+...+------+-------+ | 1 |...| 1 | NULL | +----+...+------+-------+ mysql> explain select * from part where p_type = 'LARGE BRUSHED BRASS'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+

동일한 고려 사항이 "같지 않음" 테스트에는 적용되지 않고 ~보다 작음/~보다 큼/같음 또는 BETWEEN과 같은 범위 비교에 적용됩니다. 옵티마이저는 스캔할 행의 수를 추산하고 I/O의 전체 볼륨을 기반으로 병렬 쿼리가 가치 있는지 여부를 결정합니다.

조인

대용량 테이블에서의 조인 쿼리는 일반적으로 병렬 쿼리 최적화로부터 이점을 얻는 데이터 집약적인 작업을 포함합니다. 여러 테이블 간에 열 값의 비교는(즉, 조인 조건자 자체) 현재 병렬화되지 않습니다. 하지만, 병렬 쿼리는 해시 조인 동안 Bloom 필터 생성과 같은 다른 조인 단계를 위한 내부 처리의 일부를 푸시 다운할 수 있습니다. 병렬 쿼리는 WHERE 절 없이도 조인 쿼리에 적용될 수 있습니다. 그러므로, 조인 쿼리는 병렬 쿼리를 사용하기 위해 WHERE 절이 필요한 규칙에는 예외입니다.

조인 처리의 각 단계는 병렬 쿼리에 적격한지 여부를 확인하기 위해 평가됩니다. 둘 이상의 단계에서 병렬 쿼리를 사용할 수 있는 경우 이러한 단계는 순차적으로 수행됩니다. 따라서, 각 조인 쿼리는 동시성 한도 면에서 단일 병렬 쿼리세션으로 계산됩니다.

예를 들어, 조인 쿼리에 조인된 테이블 중 한 테이블에서 행을 필터링하기 위한 WHERE 조건자가 포함된 경우, 해당 필터링 옵션은 병렬 쿼리를 사용할 수 있습니다. 다른 예로서 예를 들어, 큰 테이블을 작은 테이블과 조인하기 위해 조인 쿼리가 해시 조인 메커니즘을 사용한다고 가정해 봅시다. 이 사례에서는, Bloom 필터 데이터 구조를 생성하기 위한 테이블 스캔이 병렬 쿼리를 사용할 수도 있습니다.

참고

병렬 쿼리는 해시 조인 최적화에서 이익을 얻는 리소스 집약적인 쿼리 유형에 일반적으로 사용됩니다. 해시 조인 최적화를 설정하는 방법은 Aurora MySQL 버전에 따라 다릅니다. 각 버전에 대한 자세한 내용은 병렬 쿼리 클러스터에 대한 해시 조인 설정 섹션을 참조하세요. 해시 조인을 효과적으로 사용하는 방법에 대한 자세한 내용은 해시 조인을 사용하여 대규모 Aurora MySQL 조인 쿼리 최적화 섹션을 참조하세요.

mysql> explain select count(*) from orders join customer where o_custkey = c_custkey; +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | id |...| table | type | possible_keys | key |...| rows | Extra | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | 1 |...| customer | index | PRIMARY | c_nationkey |...| 15051972 | Using index | | 1 |...| orders | ALL | o_custkey | NULL |...| 154545408 | Using join buffer (Hash Join Outer table orders); Using parallel query (1 columns, 0 filters, 1 exprs; 0 extra) | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+

중첩 루프 메커니즘을 사용하는 조인 쿼리의 경우, 가장 바깥쪽 중첩 루프 블록은 병렬 쿼리를 사용할 수도 있습니다. 병렬 쿼리의 사용은 평상시처럼 동일한 요인(예: WHERE 절에 추가 필터 조건의 유무)에 의존합니다.

mysql> -- Nested loop join with extra filter conditions can use parallel query. mysql> explain select count(*) from part, partsupp where p_partkey != ps_partkey and p_name is not null and ps_availqty > 0; +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | | 1 | SIMPLE | partsupp |...| 78164450 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+

하위 쿼리

외부 쿼리 블록 및 내부 하위 쿼리 블록은 각각 병렬 쿼리를 사용하거나 사용하지 않을 수 있습니다. 이는 각 블록에 대한 테이블의 일반적인 특성, WHERE 절 등을 기반으로 합니다. 예를 들어, 다음 쿼리는 하위 쿼리 블록에 대해서는 병렬 쿼리를 사용하지만 외부 블록에 대해서는 사용하지 않습니다.

mysql> explain select count(*) from part where --> p_partkey < (select max(p_partkey) from part where p_name like '%vanilla%'); +----+-------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| NULL | Impossible WHERE noticed after reading const tables | | 2 | SUBQUERY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+-------------+...+----------+----------------------------------------------------------------------------+

현재, 상관관계가 있는 하위 쿼리는 병렬 쿼리 최적화를 사용할 수 없습니다.

UNION

UNION 쿼리의 각 쿼리 블록은 WHERE의 각 부분에 대하여 테이블의 일반적인 특성, UNION 절 등을 기반으로 병렬 쿼리를 사용할 수 있거나 사용할 수 없습니다.

mysql> explain select p_partkey from part where p_name like '%choco_ate%' -> union select p_partkey from part where p_name like '%vanil_a%'; +----+----------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+----------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | 2 | UNION |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | NULL | UNION RESULT | <union1,2> |...| NULL | Using temporary | +----+--------------+...+----------+----------------------------------------------------------------------------+
참고

쿼리 내의 각 UNION 절은 순차적으로 실행됩니다. 쿼리가 모두 병렬 쿼리를 사용하는 여러 단계를 포함한 경우에도, 한 번에 하나의 병렬 쿼리만 실행합니다. 그러므로, 복잡한 다단계 쿼리조차도 동시 병렬 쿼리의 한도에 1로만 가산됩니다.

보기

옵티마이저는 기본 테이블을 사용하는 더 긴 쿼리로 보기를 사용하는 쿼리를 재작성합니다. 따라서, 병렬 쿼리는 테이블 참조가 보기이든 실제 테이블이든 관계 없이 동일하게 작동합니다. 쿼리에 병렬 쿼리를 사용할지 여부 및 어떤 부분을 푸시 다운할지에 대해 모두 동일한 고려 사항이 최종적으로 재작성된 쿼리에 적용됩니다.

예를 들어, 다음 쿼리 계획은 일반적으로 병렬 쿼리를 사용하지 않는 보기 정의를 보여줍니다. 보기가 추가 WHERE 절로 쿼리되는 경우 Aurora MySQL은 병렬 쿼리를 사용합니다.

mysql> create view part_view as select * from part; mysql> explain select count(*) from part_view where p_partkey is not null; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 0 filters, 0 exprs; 1 extra) | +----+...+----------+----------------------------------------------------------------------------+

데이터 조작 언어(DML) 문

INSERT 부분이 병렬 쿼리를 위한 다른 조건에 부합하는 경우, SELECT 문이 처리의 SELECT 단계에 병렬 쿼리를 사용할 수 있습니다.

mysql> create table part_subset like part; mysql> explain insert into part_subset select * from part where p_mfgr = 'Manufacturer#1'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
참고

일반적으로, INSERT 문 뒤에 새로 삽입된 행을 위한 데이터는 버퍼 풀에 있습니다. 그러므로, 테이블이 많은 수의 행을 삽입한 직후에는 병렬 쿼리에 적격하지 않을 수도 있습니다. 나중에 데이터가 정상 작동 중에 버퍼 풀에서 제거된 후, 테이블에 대한 쿼리가 다시 병렬 쿼리를 사용하기 시작할 수 있습니다.

문의 CREATE TABLE AS SELECT 부분이 다른 식으로 병렬 쿼리에 적격할 수 있는 경우에도 SELECT 문은 병렬 쿼리를 사용하지 않습니다. 이 문의 DDL 부분으로 인하여 병렬 쿼리 처리와 호환되지 않게 됩니다. 반면, INSERT ... SELECT 문에서는 SELECT 부분이 병렬 쿼리를 사용할 수 있습니다.

테이블의 크기 및 DELETE 절의 조건자에 관계 없이 UPDATE 또는 WHERE 문에는 병렬 쿼리가 사용되지 않습니다.

mysql> explain delete from part where p_name is not null; +----+-------------+...+----------+-------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+-------------+ | 1 | SIMPLE |...| 20427936 | Using where | +----+-------------+...+----------+-------------+

트랜잭션 및 잠금

Aurora 기본 인스턴스에서 모든 격리 수준을 사용할 수 있습니다.

Aurora 리더 DB 인스턴스의 경우 REPEATABLE READ 격리 수준에서 수행되는 문에 병렬 쿼리가 적용됩니다. 또한 Aurora MySQL 버전2.09 이상에서는 리더 DB 인스턴스에서 READ COMMITTED 격리 수준을 사용할 수 있습니다. REPEATABLE READ는 Aurora 리더 DB 인스턴스에 대한 기본 격리 수준입니다. 읽기 전용 DB 인스턴스에서 READ COMMITTED 격리 수준을 사용하려면 세션 수준에서 aurora_read_replica_read_committed 구성 옵션을 설정해야 합니다. 리더 인스턴스의 READ COMMITTED 격리 수준은 SQL 표준 동작을 준수합니다. 그러나 리더 인스턴스의 격리는 쿼리가 작성자 인스턴스에서 READ COMMITTED 격리를 사용하는 경우보다 덜 엄격합니다.

Aurora 격리 수준, 특히 작성자 인스턴스와 리더 인스턴스 간 READ COMMITTED 차이점에 대한 자세한 내용은 Aurora MySQL 격리 수준 섹션을 참조하세요.

대형 트랜잭션이 완료된 후에는 테이블 통계가 기한 경과될 수 있습니다. Aurora가 행의 수를 정확하게 추산할 수 있으려면 먼저 그러한 기한 경과 통계에 ANALYZE TABLE 문이 필요할 수 있습니다. 대규모 DML 문 또한 테이블 데이터의 상당 부분을 버퍼 풀로 가져올 수 있습니다. 이러한 데이터가 버퍼 풀에 있으면 데이터가 풀에서 제거될 때까지 해당 테이블에 대해 병렬 쿼리가 덜 자주 선택될 수 있습니다.

세션이 장기 실행 트랙잭션(기본적으로 10분) 내부에 있는 경우, 해당 세션 내부의 추가 쿼리는 병렬 쿼리를 사용하지 않습니다. 또한 단일 장기 실행 쿼리 동안 시간 초과가 발생할 수 있습니다. 병렬 쿼리 처리가 시작되기 전에 쿼리가 최대 간격(현재 10분)보다 더 오래 실행되는 경우 이러한 유형의 시간 초과가 발생할 수 있습니다.

임시(1회) 쿼리를 수행하는 autocommit=1 세션에 mysql을 설정하여 실수로 장기 실행 트랜잭션을 시작할 가능성을 줄일 수 있습니다. 읽기 보기를 만들면 테이블에 대한 SELECT 문도 트랜잭션을 시작합니다. 읽기 보기는 트랜잭션이 커밋될 때까지 남아있는 후속 쿼리를 위한 일관된 데이터 집합입니다. Aurora에서 JDBC 또는 ODBC 애플리케이션을 사용할 때도 이러한 제한에 유의하십시오. 이러한 애플리케이션은 autocommit 설정이 꺼진 상태에서도 실행될 수 있기 때문입니다.

다음은 autocommit 설정이 꺼진 상태에서, 테이블에 대한 쿼리 실행이 트랜잭션을 암시적으로 시작하는 읽기 보기를 생성하는 방법을 보여주는 예제입니다. 그 후에 짧게 실행되는 쿼리는 여전히 병렬 쿼리를 사용할 수 있습니다. 하지만, 몇 분간 일시 정지 후에는 쿼리가 병렬 쿼리에 더 이상 적격하지 않습니다. COMMIT 또는 ROLLBACK으로 트랜잭션을 종료하면 병렬 쿼리 자격을 복원합니다.

mysql> set autocommit=0; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+ mysql> select sleep(720); explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +------------+ | sleep(720) | +------------+ | 0 | +------------+ 1 row in set (12 min 0.00 sec) +----+...+---------+-------------+ | id |...| rows | Extra | +----+...+---------+-------------+ | 1 |...| 2976129 | Using where | +----+...+---------+-------------+ mysql> commit; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+

쿼리가 장기 실행 트랜잭션 내부에 있었기 때문에 병렬 쿼리에 적격하지 않은 횟수를 확인하려면 상태 변수 Aurora_pq_request_not_chosen_long_trx를 확인합니다.

mysql> show global status like '%pq%trx%'; +---------------------------------------+-------+ | Variable_name | Value | +---------------------------------------+-------+ | Aurora_pq_request_not_chosen_long_trx | 4 | +-------------------------------+-------+

SELECT 또는 SELECT FOR UPDATE 구문과 같은 잠금을 획득하는 SELECT LOCK IN SHARE MODE 문은 병렬 쿼리를 사용할 수 없습니다.

병렬 쿼리는 LOCK TABLES 문에 의해 잠겨진 테이블을 위해 작동할 수 있습니다.

mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055'; +----+...+-----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+-----------+----------------------------------------------------------------------------+ | 1 |...| 154545408 | Using where; Using parallel query (3 columns, 1 filters, 0 exprs; 0 extra) | +----+...+-----------+----------------------------------------------------------------------------+ mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055' for update; +----+...+-----------+-------------+ | id |...| rows | Extra | +----+...+-----------+-------------+ | 1 |...| 154545408 | Using where | +----+...+-----------+-------------+

B-트리 인덱스

ANALYZE TABLE 문에 의해 수집된 통계는 옵티마이저가 각 열에 대한 데이터의 특성을 기반으로 병렬 쿼리 또는 인덱스 조회를 사용하는 경우를 결정하도록 도와줍니다. 테이블 내의 데이터에 상당한 변경을 적용하는 DML 작업 후에 ANALYZE TABLE을 실행하여 통계를 현재 상태로 유지하십시오.

인덱스 조회가 데이터 집약적인 스캔 없이도 효율적으로 쿼리를 수행할 수 있는 경우 Aurora은 인덱스 조회를 사용할 수도 있습니다. 그렇게 하면 병렬 쿼리 처리의 오버헤드를 피할 수 있습니다. 또한 Aurora DB 클러스터에서 동시에 실행될 수 있는 병렬 쿼리의 수에 대한 동시성 제한도 있습니다. 가장 빈번하게 가장 많이 사용되는 동시 쿼리가 인덱스 조회를 사용하도록, 테이블 인덱싱을 위한 모범 사례를 사용하십시오.

전체 텍스트 검색(FTS) 인덱스

현재, 병렬 쿼리는 전체 텍스트 검색 인덱스를 포함한 테이블에 사용되지 않습니다(쿼리가 그러한 인덱싱된 열을 참조하든 MATCH 연산자를 사용하든 관계 없음).

가상 열

현재 쿼리가 가상 열을 참조하는지 여부에 관계없이 가상 열이 포함된 테이블에는 병렬 쿼리가 사용되지 않습니다.

내장된 캐싱 메커니즘

Aurora에는 내장된 캐싱 메커니즘(즉, 버퍼 풀 및 쿼리 캐시)이 포함되어 있습니다. Aurora 옵티마이저는 어떤 것이 특정 쿼리에 가장 효과적인지에 따라서 이러한 캐싱 메커니즘과 병렬 쿼리 중에서 선택합니다.

병렬 쿼리가 행을 필터링하고 열 값을 변환 및 추출할 때, 데이터는 데이터 페이지가 아니라 튜플로 다시 헤드 노드에 전송됩니다. 그러므로, 병렬 쿼리를 실행해도 버퍼 풀에 페이지가 추가되거나 버퍼 풀에 이미 존재하는 페이지가 제거되지 않습니다.

Aurora는 버퍼 풀에 있는 테이블 데이터의 페이지 수와 해당 숫자가 나타내는 테이블 데이터의 비율을 확인합니다. Aurora는 이 정보를 사용하여 병렬 쿼리(및 버퍼 풀의 데이터 우회)를 사용하는 것이 더 효율적인지 여부를 결정합니다. 또는 Aurora은 버퍼 풀에 캐시된 데이터를 사용하는 비병렬 쿼리 처리 경로를 사용할 수도 있습니다. 어떤 페이지가 캐시되고 데이터 집약적인 쿼리가 캐싱 및 제거에 어떠한 영향을 미치는지는 버퍼 풀에 관련된 구성 설정에 따라 다릅니다. 따라서 선택은 버퍼 풀 내에서 끊임없이 변하는 데이터에 달려 있기 때문에, 특정 쿼리가 병렬 쿼리를 사용할지 여부를 예측하기는 어려울 수 있습니다.

또한, Aurora은 병렬 쿼리에 동시성 한도를 적용합니다. 모든 쿼리가 병렬 쿼리를 사용하는 것은 아니기 때문에, 여러 쿼리에 의해 동시에 액세스되는 테이블은 일반적으로 버퍼 풀에 데이터의 상당 부분이 있습니다. 따라서, Aurora은 대개 병렬 쿼리를 위해 이러한 테이블은 선택하지 않습니다.

동일한 테이블에서 비병렬 쿼리의 시퀀스를 실행하는 경우, 첫 번째 쿼리는 데이터가 버퍼 풀에 없어서 오래 걸릴 수 있습니다. 그런 다음 두 번째 및 이후 쿼리는 버퍼 풀이 이제 "워밍업"되어서 훨씬 더 빨라집니다. 병렬 쿼리는 일반적으로 테이블에 대한 맨 첫 번째 쿼리부터 일관된 성능을 보여줍니다. 성능 테스트를 수행할 때는 콜드(cold) 버퍼 풀과 웜(warm) 버퍼 풀에서 모두 비병렬 쿼리를 벤치마크합니다. 일부 경우, 웜 버퍼 풀에서의 결과는 병렬 쿼리 시간과 잘 비교될 수 있습니다. 이러한 경우 해당 테이블에 대한 쿼리 빈도와 같은 요소를 고려합니다. 또한 버퍼 풀에 해당 테이블의 데이터를 유지하는 것이 가치가 있는지 여부를 고려해야 합니다.

동일한 쿼리가 제출되고 기본 테이블 데이터가 변경되지 않은 경우 쿼리 캐시는 쿼리 재실행을 방지합니다. 병렬 쿼리 기능에 의해 최적화된 쿼리는 쿼리 캐시로 이동할 수 있어, 쿼리가 다시 실행될 때 즉각적으로 실행되므로 효율적입니다.

참고

성능 비교를 수행할 때, 쿼리 캐시가 인위적으로 낮은 시간 지정 숫자를 생성할 수 있습니다. 따라서, 벤치마크 같은 상황에서는 sql_no_cache 힌트를 사용할 수 있습니다. 이 힌트는 이전에 동일한 쿼리가 실행된 경우에도, 결과가 쿼리 캐시로부터 제공되지 않도록 합니다. 힌트는 쿼리의 SELECT 문 바로 뒤에 옵니다. 병렬 쿼리가 설정 및 해제된 쿼리의 버전들 간에 쿼리 시간이 비교 가능해지도록 이 주제의 많은 병렬 쿼리 예에 이 힌트가 포함되어 있습니다.

병렬 쿼리의 프로덕션용으로 이동할 때는 원본에서 이 힌트를 제거해야 합니다.

최적화 프로그램 힌트

최적화 프로그램을 제어하는 또 다른 방법은 개별 문 내에서 지정할 수 있는 최적화 프로그램 힌트를 사용하는 것입니다. 예를 들어, 문 안에 있는 한 테이블에 대해 최적화를 설정한 다음 다른 테이블에 대한 최적화를 끌 수 있습니다. 이러한 힌트에 대한 자세한 내용은 MySQL 참조 설명서최적화 프로그램 힌트를 참조하세요.

Aurora MySQL 쿼리와 함께 SQL 힌트를 사용하여 성능을 미세 조정할 수 있습니다. 또한 힌트를 사용하여 예기치 않은 조건으로 인해 중요한 쿼리에 대한 실행 계획이 변경되는 것을 방지할 수 있습니다.

쿼리 계획에 대한 최적화 프로그램 선택 항목을 제어할 수 있도록 SQL 힌트 기능을 확장했습니다. 이러한 힌트는 병렬 쿼리 최적화를 사용하는 쿼리에 적용됩니다. 자세한 내용은 Aurora MySQL 힌트 섹션을 참조하세요.

MyISAM 임시 테이블

병렬 쿼리 최적화는 InnoDB 테이블에만 적용됩니다. Aurora MySQL은 임시 테이블을 위해 배후에서 MyISAM을 사용하기 때문에, 임시 테이블을 포함하는 내부 쿼리 단계는 병렬 쿼리를 사용합니다. 이러한 쿼리 단계는 Using temporary 출력에서 EXPLAIN로 표시됩니다.