PartiQL 문 통계 가져오기 - Amazon Quantum Ledger Database(QLDB)

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

PartiQL 문 통계 가져오기

Amazon QLDB는 보다 효율적인 PartiQL 문을 실행하여 QLDB 사용을 최적화하는 데 도움이 되는 문 실행 통계를 제공합니다. QLDB는 명령문의 결과와 함께 이러한 통계를 반환합니다. 여기에는 소비된 I/O 사용량과 서버 측 처리 시간을 정량화하는 지표가 포함되며, 이를 통해 비효율적인 명령문을 식별할 수 있습니다.

이 기능은 현재 QLDB 콘솔PartiQL 편집기, QLDB 쉘 및 지원되는 모든 언어에 대한 최신 버전의 QLDB 드라이버에서 사용할 수 있습니다. 콘솔에서 쿼리 기록에 대한 명령문 통계를 볼 수도 있습니다.

I/O 사용량

I/O 사용량 지표는 읽기 I/O 요청 수를 설명합니다. 읽기 I/O 요청 수가 예상보다 많으면 인덱스 부족 등 명령문이 최적화되지 않았음을 나타냅니다. 이전 항목인 쿼리 성능 최적화에서 최적의 쿼리 패턴를 검토하는 것이 좋습니다.

참고

비어 있지 않은 테이블에서 CREATE INDEX 명령문을 실행하면 I/O 사용량 지표에는 동기 인덱스 생성 호출에 대한 읽기 요청만 포함됩니다.

QLDB는 테이블의 기존 문서에 대한 인덱스를 비동기적으로 빌드합니다. 이러한 비동기 읽기 요청은 명령문 결과의 I/O 사용량 지표에 포함되지 않습니다. 비동기 읽기 요청은 별도로 요금이 부과되며 인덱스 빌드가 완료된 후 총 읽기 I/O에 추가됩니다.

QLDB 콘솔 사용

QLDB 콘솔을 사용하여 명령문의 읽기 I/O 사용량을 확인하려면 다음 단계를 수행하세요.

  1. https://console.aws.amazon.com/qldb에서 Amazon QLDB 콘솔을 엽니다.

  2. 탐색 창에서 PartiQL 편집기를 선택합니다.

  3. 원장 드롭다운 목록에서 원장을 선택합니다.

  4. 쿼리 편집기 창에서 선택한 문을 입력한 다음 실행을 선택합니다. 다음은 쿼리 예제입니다.

    SELECT * FROM testTable WHERE firstName = 'Jim'

    명령문을 실행하려면 키보드 단축키 (Windows의 경우 Ctrl+Enter, macOS의 경우 Cmd+Return)를 사용할 수도 있습니다. 키보드 단축키에 대한 자세한 내용은 PartiQL 편집기 키보드 바로 가기 섹션을 참조하세요.

  5. 쿼리 편집기 창 아래에 쿼리 결과에는 명령문에 의해 수행된 읽기 요청 횟수인 읽기 I/O가 포함됩니다.

다음 단계를 수행하여 쿼리 기록의 읽기 I/O를 볼 수도 있습니다.

  1. 탐색 창의 PartiQL 편집기에서 최근 쿼리를 선택합니다.

  2. 읽기 I/O 열에는 각 명령문에서 이루어진 읽기 요청 수가 표시됩니다.

QLDB 드라이버 사용

QLDB 드라이버를 사용하여 명령문의 I/O 사용량을 가져오려면 결과의 스트림 커서 또는 버퍼링된 커서의 getConsumedIOs 작업을 호출하세요.

다음 코드 예제는 문 결과의 스트림 커서에서 읽기 I/O를 가져오는 방법을 보여줍니다.

Java
import com.amazon.ion.IonSystem; import com.amazon.ion.IonValue; import com.amazon.ion.system.IonSystemBuilder; import software.amazon.qldb.IOUsage; import software.amazon.qldb.Result; IonSystem ionSystem = IonSystemBuilder.standard().build(); IonValue ionFirstName = ionSystem.newString("Jim"); driver.execute(txn -> { Result result = txn.execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); for (IonValue ionValue : result) { // User code here to handle results } IOUsage ioUsage = result.getConsumedIOs(); long readIOs = ioUsage.getReadIOs(); });
.NET
using Amazon.IonDotnet.Builders; using Amazon.IonDotnet.Tree; using Amazon.QLDB.Driver; using IAsyncResult = Amazon.QLDB.Driver.IAsyncResult; // This is one way of creating Ion values. We can also use a ValueFactory. // For more details, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-cookbook-dotnet.html#cookbook-dotnet.ion IIonValue ionFirstName = IonLoader.Default.Load("Jim"); await driver.Execute(async txn => { IAsyncResult result = await txn.Execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); // Iterate through stream cursor to accumulate read IOs. await foreach (IIonValue ionValue in result) { // User code here to handle results. // Warning: It is bad practice to rely on results within a lambda block, unless // it is to check the state of a result. This is because lambdas are retryable. } var ioUsage = result.GetConsumedIOs(); var readIOs = ioUsage?.ReadIOs; });
참고

동기 코드로 변환하려면 awaitasync 키워드를 제거하고 IAsyncResult 유형을 IResult로 변경하세요.

Go
import ( "context" "fmt" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT * FROM testTable WHERE firstName = ?", "Jim") if err != nil { panic(err) } for result.Next(txn) { // User code here to handle results } ioUsage := result.GetConsumedIOs() readIOs := *ioUsage.GetReadIOs() fmt.Println(readIOs) return nil,nil })
Node.js
import { IOUsage, ResultReadable, TransactionExecutor } from "amazon-qldb-driver-nodejs"; await driver.executeLambda(async (txn: TransactionExecutor) => { const result: ResultReadable = await txn.executeAndStreamResults("SELECT * FROM testTable WHERE firstName = ?", "Jim"); for await (const chunk of result) { // User code here to handle results } const ioUsage: IOUsage = result.getConsumedIOs(); const readIOs: number = ioUsage.getReadIOs(); });
Python
def get_read_ios(transaction_executor): cursor = transaction_executor.execute_statement("SELECT * FROM testTable WHERE firstName = ?", "Jim") for row in cursor: # User code here to handle results pass consumed_ios = cursor.get_consumed_ios() read_ios = consumed_ios.get('ReadIOs') qldb_driver.execute_lambda(lambda txn: get_read_ios(txn))

다음 코드 예제는 문 결과의 버퍼된 커서에서 읽기 I/O를 가져오는 방법을 보여줍니다. 그러면 ExecuteStatementFetchPage 요청의 총 읽기 I/O가 반환됩니다.

Java
import com.amazon.ion.IonSystem; import com.amazon.ion.IonValue; import com.amazon.ion.system.IonSystemBuilder; import software.amazon.qldb.IOUsage; import software.amazon.qldb.Result; IonSystem ionSystem = IonSystemBuilder.standard().build(); IonValue ionFirstName = ionSystem.newString("Jim"); Result result = driver.execute(txn -> { return txn.execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); }); IOUsage ioUsage = result.getConsumedIOs(); long readIOs = ioUsage.getReadIOs();
.NET
using Amazon.IonDotnet.Builders; using Amazon.IonDotnet.Tree; using Amazon.QLDB.Driver; using IAsyncResult = Amazon.QLDB.Driver.IAsyncResult; IIonValue ionFirstName = IonLoader.Default.Load("Jim"); IAsyncResult result = await driver.Execute(async txn => { return await txn.Execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); }); var ioUsage = result.GetConsumedIOs(); var readIOs = ioUsage?.ReadIOs;
참고

동기 코드로 변환하려면 awaitasync 키워드를 제거하고 IAsyncResult 유형을 IResult로 변경하세요.

Go
import ( "context" "fmt" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) result, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT * FROM testTable WHERE firstName = ?", "Jim") if err != nil { return nil, err } return txn.BufferResult(result) }) if err != nil { panic(err) } qldbResult := result.(*qldbdriver.BufferedResult) ioUsage := qldbResult.GetConsumedIOs() readIOs := *ioUsage.GetReadIOs() fmt.Println(readIOs)
Node.js
import { IOUsage, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; const result: Result = await driver.executeLambda(async (txn: TransactionExecutor) => { return await txn.execute("SELECT * FROM testTable WHERE firstName = ?", "Jim"); }); const ioUsage: IOUsage = result.getConsumedIOs(); const readIOs: number = ioUsage.getReadIOs();
Python
cursor = qldb_driver.execute_lambda( lambda txn: txn.execute_statement("SELECT * FROM testTable WHERE firstName = ?", "Jim")) consumed_ios = cursor.get_consumed_ios() read_ios = consumed_ios.get('ReadIOs')
참고

스트림 커서는 결과 집합의 페이지를 매기므로 상태를 추적할 수 있습니다. 따라서 getConsumedIOsgetTimingInformation 연산은 호출한 시점부터 누적된 지표를 반환합니다.

버퍼링된 커서는 결과 집합을 메모리에 버퍼링하고 총 누적된 지표를 반환합니다.

타이밍 정보

타이밍 정보 지표는 서버 측 처리 시간을 밀리초 단위로 설명합니다. 서버측 처리 시간은 QLDB가 명령문을 처리하는 데 소비하는 시간으로 정의됩니다. 네트워크 호출 또는 일시 중지에 소요된 시간은 여기에 포함되지 않습니다. 이 메트릭은 QLDB 서비스 측의 처리 시간과 클라이언트 측의 처리 시간을 구분합니다.

QLDB 콘솔 사용

QLDB 콘솔을 사용하여 명령문의 타이밍 정보를 가져오려면 다음 단계를 수행하세요.

  1. https://console.aws.amazon.com/qldb에서 Amazon QLDB 콘솔을 엽니다.

  2. 탐색 창에서 PartiQL 편집기를 선택합니다.

  3. 원장 드롭다운 목록에서 원장을 선택합니다.

  4. 쿼리 편집기 창에서 선택한 문을 입력한 다음 실행을 선택합니다. 다음은 쿼리 예제입니다.

    SELECT * FROM testTable WHERE firstName = 'Jim'

    명령문을 실행하려면 키보드 단축키 (Windows의 경우 Ctrl+Enter, macOS의 경우 Cmd+Return)를 사용할 수도 있습니다. 키보드 단축키에 대한 자세한 내용은 PartiQL 편집기 키보드 바로 가기 섹션을 참조하세요.

  5. 쿼리 편집기 창 아래에 쿼리 결과에는 QLDB가 명령문 요청을 수신한 시점과 응답을 보낸 시점 사이의 시간인 서버 측 지연 시간이 포함됩니다. 이는 총 쿼리 기간의 하위 집합입니다.

다음 단계를 수행하여 쿼리 기록의 타이밍 정보를 볼 수도 있습니다.

  1. 탐색 창의 PartiQL 편집기에서 최근 쿼리를 선택합니다.

  2. 실행 시간(밀리초) 열에는 각 명령문에 대한 이 타이밍 정보가 표시됩니다.

QLDB 드라이버 사용

QLDB 드라이버를 사용하여 명령문의 타이밍 정보를 가져오려면 결과의 스트림 커서 또는 버퍼링된 커서의 getTimingInformation 작업을 호출하세요.

다음 코드 예제는 문 결과의 스트림 커서에서 처리 시간을 가져오는 방법을 보여줍니다.

Java
import com.amazon.ion.IonSystem; import com.amazon.ion.IonValue; import com.amazon.ion.system.IonSystemBuilder; import software.amazon.qldb.Result; import software.amazon.qldb.TimingInformation; IonSystem ionSystem = IonSystemBuilder.standard().build(); IonValue ionFirstName = ionSystem.newString("Jim"); driver.execute(txn -> { Result result = txn.execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); for (IonValue ionValue : result) { // User code here to handle results } TimingInformation timingInformation = result.getTimingInformation(); long processingTimeMilliseconds = timingInformation.getProcessingTimeMilliseconds(); });
.NET
using Amazon.IonDotnet.Builders; using Amazon.IonDotnet.Tree; using Amazon.QLDB.Driver; using IAsyncResult = Amazon.QLDB.Driver.IAsyncResult; IIonValue ionFirstName = IonLoader.Default.Load("Jim"); await driver.Execute(async txn => { IAsyncResult result = await txn.Execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); // Iterate through stream cursor to accumulate processing time. await foreach(IIonValue ionValue in result) { // User code here to handle results. // Warning: It is bad practice to rely on results within a lambda block, unless // it is to check the state of a result. This is because lambdas are retryable. } var timingInformation = result.GetTimingInformation(); var processingTimeMilliseconds = timingInformation?.ProcessingTimeMilliseconds; });
참고

동기 코드로 변환하려면 awaitasync 키워드를 제거하고 IAsyncResult 유형을 IResult로 변경하세요.

Go
import ( "context" "fmt" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT * FROM testTable WHERE firstName = ?", "Jim") if err != nil { panic(err) } for result.Next(txn) { // User code here to handle results } timingInformation := result.GetTimingInformation() processingTimeMilliseconds := *timingInformation.GetProcessingTimeMilliseconds() fmt.Println(processingTimeMilliseconds) return nil, nil })
Node.js
import { ResultReadable, TimingInformation, TransactionExecutor } from "amazon-qldb-driver-nodejs"; await driver.executeLambda(async (txn: TransactionExecutor) => { const result: ResultReadable = await txn.executeAndStreamResults("SELECT * FROM testTable WHERE firstName = ?", "Jim"); for await (const chunk of result) { // User code here to handle results } const timingInformation: TimingInformation = result.getTimingInformation(); const processingTimeMilliseconds: number = timingInformation.getProcessingTimeMilliseconds(); });
Python
def get_processing_time_milliseconds(transaction_executor): cursor = transaction_executor.execute_statement("SELECT * FROM testTable WHERE firstName = ?", "Jim") for row in cursor: # User code here to handle results pass timing_information = cursor.get_timing_information() processing_time_milliseconds = timing_information.get('ProcessingTimeMilliseconds') qldb_driver.execute_lambda(lambda txn: get_processing_time_milliseconds(txn))

다음 코드 예제는 문 결과의 버퍼된 커서에서 처리 시간을 가져오는 방법을 보여줍니다. 그러면 ExecuteStatementFetchPage 요청의 총 처리 시간이 반환됩니다.

Java
import com.amazon.ion.IonSystem; import com.amazon.ion.IonValue; import com.amazon.ion.system.IonSystemBuilder; import software.amazon.qldb.Result; import software.amazon.qldb.TimingInformation; IonSystem ionSystem = IonSystemBuilder.standard().build(); IonValue ionFirstName = ionSystem.newString("Jim"); Result result = driver.execute(txn -> { return txn.execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); }); TimingInformation timingInformation = result.getTimingInformation(); long processingTimeMilliseconds = timingInformation.getProcessingTimeMilliseconds();
.NET
using Amazon.IonDotnet.Builders; using Amazon.IonDotnet.Tree; using Amazon.QLDB.Driver; using IAsyncResult = Amazon.QLDB.Driver.IAsyncResult; IIonValue ionFirstName = IonLoader.Default.Load("Jim"); IAsyncResult result = await driver.Execute(async txn => { return await txn.Execute("SELECT * FROM testTable WHERE firstName = ?", ionFirstName); }); var timingInformation = result.GetTimingInformation(); var processingTimeMilliseconds = timingInformation?.ProcessingTimeMilliseconds;
참고

동기 코드로 변환하려면 awaitasync 키워드를 제거하고 IAsyncResult 유형을 IResult로 변경하세요.

Go
import ( "context" "fmt" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) result, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT * FROM testTable WHERE firstName = ?", "Jim") if err != nil { return nil, err } return txn.BufferResult(result) }) if err != nil { panic(err) } qldbResult := result.(*qldbdriver.BufferedResult) timingInformation := qldbResult.GetTimingInformation() processingTimeMilliseconds := *timingInformation.GetProcessingTimeMilliseconds() fmt.Println(processingTimeMilliseconds)
Node.js
import { Result, TimingInformation, TransactionExecutor } from "amazon-qldb-driver-nodejs"; const result: Result = await driver.executeLambda(async (txn: TransactionExecutor) => { return await txn.execute("SELECT * FROM testTable WHERE firstName = ?", "Jim"); }); const timingInformation: TimingInformation = result.getTimingInformation(); const processingTimeMilliseconds: number = timingInformation.getProcessingTimeMilliseconds();
Python
cursor = qldb_driver.execute_lambda( lambda txn: txn.execute_statement("SELECT * FROM testTable WHERE firstName = ?", "Jim")) timing_information = cursor.get_timing_information() processing_time_milliseconds = timing_information.get('ProcessingTimeMilliseconds')
참고

스트림 커서는 결과 집합의 페이지를 매기므로 상태를 추적할 수 있습니다. 따라서 getConsumedIOsgetTimingInformation 연산은 호출한 시점부터 누적된 지표를 반환합니다.

버퍼링된 커서는 결과 집합을 메모리에 버퍼링하고 총 누적된 지표를 반환합니다.

시스템 카탈로그를 쿼리하는 방법을 알아보려면 시스템 카탈로그 쿼리 섹션을 참조하세요.