我是 DynamoDb 的新手。因此,如果有人可以向我解释,我做错了什么,或者我在理解中错过了什么,那就太好了。 我试图找到最有效的方法来搜索包含某些值的行。 正在研究一些测试数据,看看它是如何工作的以及如何设计一切。
我有一张大约有 1700 行的表。有些行中有相当多的数据。 有 PK - Id,以及其他一些属性,如名称、国籍、描述等。 我还在“名称”上添加了 GSI,投影类型为“KEYS_ONLY”
现在,我的场景是找到一个人,该人的名字包含给定的字符串。假设名字是“Pablo Picasso”,我想找到任何“Picasso” 我的假设是,如果我扫描 GSI,它应该相当快,我理解,扫描只能扫描 !mb 的数据,但我假设,我的 GSI 看起来像这样:
姓名。 | 身份证 |
---|---|
漏斗 | 2 |
蒂莫蒂c | 3 |
唐老鸭 | 14 |
考虑到这一点,我确信它应该在第一次扫描时找到我的行。不幸的是,我的第一次扫描只扫描了 340 行。在 4 次致电 Dynamo 后,我终于找到了我的行。 当我进行类似的扫描时,但不是在 GSI 上,它需要 5 次调用。这看起来并没有什么不同。
我做错了什么吗?还是我理解错了什么?
出于测试目的,我使用如下 C# 代码:
var result = await _dynamoDb.ScanAsync(new ScanRequest(DynamoConstants.ArtistsTableName)
{
IndexName = "NameIndex",
FilterExpression = "contains(#Name, :name)",
ExpressionAttributeNames = new Dictionary<string, string>() { { "#Name", "name" } },
ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
{ { ":name", new AttributeValue("Picasso") } }
});
我的索引如下所示:
var nameIndex = new GlobalSecondaryIndex
{
IndexName = "NameIndex",
ProvisionedThroughput = new ProvisionedThroughput
{
ReadCapacityUnits = 5,
WriteCapacityUnits = 5
},
Projection = new Projection { ProjectionType = "KEYS_ONLY" },
KeySchema = new List<KeySchemaElement> {
new() { AttributeName = "name", KeyType = "HASH"}
}
};
编辑: 我做了更多挖掘,发现实际上 GSI 大小与整个表相同。
...
"TableSizeBytes": 5435537,
"ItemCount": 1792,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/artists",
"GlobalSecondaryIndexes": [
{
"IndexName": "NameIndex",
"KeySchema": [
{
"AttributeName": "name",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY"
},
"IndexStatus": "ACTIVE",
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"IndexSizeBytes": 5435537,
"ItemCount": 1792,
.....
但是为什么呢?我的索引创建有什么问题吗?
好的,我知道问题是什么了。问题是,本地版本的 dynamo db 显然很糟糕,并且它不能代表 DynamoDb 的 GSI 工作方式。
我在AWS上的实际DynamoDb上添加了具有相同索引的相同表,并且表和索引之间存在适当的大小差异。正是我想象的样子。