本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
获取 PartiQL 语句统计信息
Amazon QLDB 提供语句执行统计信息,可帮助您QLDB通过运行更高效的 PartiQL 语句来优化对的使用。QLDB返回这些统计数据以及语句的结果。它们包含量化消耗的 I/O 使用情况和服务器端处理时间的指标,您可以使用这些指标来识别低效的语句。
该功能目前可在QLDB控制台的 P artiQL 编辑器、QLDBshell 以及适用于所有支持语言的最新版本的QLDB驱动程序中使用。您还可在控制台上查看查询历史的语句统计信息。
I/O 使用率
I/O 使用率指标介绍了读取 I/O 请求的数量。如果读取 I/O 请求的数量高于预期,则表示语句未经优化,例如缺少索引。我们建议您在上一主题 优化查询性能 中复习最优查询模式。
在非空表上运行CREATE INDEX
语句时,I/O 使用率指标仅包含同步索引创建调用的读取请求。
QLDB异步为表中的任何现有文档建立索引。这些异步读取请求不包括在语句结果的 I/O 使用率指标中。异步读取请求单独收费,且在索引构建完成后计入您的读取 I/O 总数。
使用 QLDB控制台
要使用QLDB控制台获取语句的读取 I/O 使用率,请执行以下步骤:
您还可通过执行以下步骤来查看查询历史记录的读取 I/O:
-
在导航窗格中,选择PartiQL 编辑器下的最新查询。
-
读取 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;
});
要转换为同步代码,请移除 await
和 async
关键字,然后将 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。这将返回来自 ExecuteStatement
和FetchPage
请求的读取 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;
要转换为同步代码,请移除 await
和 async
关键字,然后将 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')
流指针是有状态的,因为它会对结果集分页。因此,getConsumedIOs
和getTimingInformation
操作会返回您调用这些指标时的累积指标。
缓冲后的指针将结果集缓存至内存中,并返回累积的指标总数。
计时信息指标描述了服务器端处理时间(以毫秒为单位)。服务器端处理时间定义为处理语句所QLDB花费的时间。这不包括网络通话或暂停时间。该指标可以消除QLDB服务端的处理时间与客户端的处理时间之间的歧义。
要使用QLDB控制台获取语句的时间信息,请执行以下步骤:
您还可通过执行以下步骤来查看查询历史记录的计时信息:
-
在导航窗格中,选择PartiQL 编辑器下的最新查询。
-
执行时间(ms)列将会显示每条语句的计时信息。
要使用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;
});
要转换为同步代码,请移除 await
和 async
关键字,然后将 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))
以下代码示例显示如何从语句结果的 缓冲指针 中获取处理时间。这将返回来自 ExecuteStatement
和FetchPage
请求的总处理时间。
- 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;
要转换为同步代码,请移除 await
和 async
关键字,然后将 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')
流指针是有状态的,因为它会对结果集分页。因此,getConsumedIOs
和getTimingInformation
操作会返回您调用这些指标时的累积指标。
缓冲后的指针将结果集缓存至内存中,并返回累积的指标总数。
要了解如何查询系统目录,请继续 查询系统目录。