取得 PartiQL 陳述式統計 - Amazon Quantum Ledger Database (Amazon 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. 開啟亞馬遜 QLDB 主控台,網址為 https://console.aws.amazon.com/qldb

  2. 在導覽窗格中,選擇 PartiQL 編輯器

  3. 從分類帳的下拉式清單中選擇分類帳。

  4. 在查詢編輯器視窗中,輸入您選擇的任何陳述式,然後選擇 [執行]。以下是查詢範例。

    SELECT * FROM testTable WHERE firstName = 'Jim'

    若要執行陳述式,您也可以使用鍵盤快速鍵Ctrl + (適用Enter於 Windows) 或Cmd + (適用Return於 macOS)。如需更多鍵盤快速鍵,請參閱編 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. 開啟亞馬遜 QLDB 主控台,網址為 https://console.aws.amazon.com/qldb

  2. 在導覽窗格中,選擇 PartiQL 編輯器

  3. 從分類帳的下拉式清單中選擇分類帳。

  4. 在查詢編輯器視窗中,輸入您選擇的任何陳述式,然後選擇 [執行]。以下是查詢範例。

    SELECT * FROM testTable WHERE firstName = 'Jim'

    若要執行陳述式,您也可以使用鍵盤快速鍵Ctrl + (適用Enter於 Windows) 或Cmd + (適用Return於 macOS)。如需更多鍵盤快速鍵,請參閱編 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作業會從您呼叫時傳回累積量度。

緩衝的游標會緩衝記憶體中的結果集,並傳回累計量的總計量度。

若要瞭解如何查詢系統目錄,請繼續執行查詢系統目錄