Python 遍历DynamoDB表中的所有项

Python 遍历DynamoDB表中的所有项,python,amazon-web-services,amazon-dynamodb,Python,Amazon Web Services,Amazon Dynamodb,我正在尝试遍历DynamoDB表中的所有项。(我知道这是一个低效的过程,但我只是一次性地构建索引表。) 我知道DynamoDB的scan()函数返回1MB或提供的限制中的较小值。为了弥补这一点,我编写了一个函数来查找“LastEvaluatedKey”结果,并从LastEvaluatedKey开始重新查询以获得所有结果 不幸的是,似乎每次我的函数循环时,整个数据库中的每一个键都会被扫描,很快就会耗尽我分配的读取单元。非常慢 这是我的密码: def search(table, scan_filte

我正在尝试遍历DynamoDB表中的所有项。(我知道这是一个低效的过程,但我只是一次性地构建索引表。)

我知道DynamoDB的scan()函数返回1MB或提供的限制中的较小值。为了弥补这一点,我编写了一个函数来查找“LastEvaluatedKey”结果,并从LastEvaluatedKey开始重新查询以获得所有结果

不幸的是,似乎每次我的函数循环时,整个数据库中的每一个键都会被扫描,很快就会耗尽我分配的读取单元。非常慢

这是我的密码:

def search(table, scan_filter=None, range_key=None,
           attributes_to_get=None,
           limit=None):
    """ Scan a database for values and return
        a dict.
    """

    start_key = None
    num_results = 0
    total_results = []
    loop_iterations = 0
    request_limit = limit

    while num_results < limit:
        results = self.conn.layer1.scan(table_name=table,
                                  attributes_to_get=attributes_to_get,
                                  exclusive_start_key=start_key,
                                  limit=request_limit)
        num_results = num_results + len(results['Items'])
        start_key = results['LastEvaluatedKey']
        total_results = total_results + results['Items']
        loop_iterations = loop_iterations + 1
        request_limit = request_limit - results['Count']

        print "Count: " + str(results['Count'])
        print "Scanned Count: " + str(results['ScannedCount'])
        print "Last Evaluated Key: " + str(results['LastEvaluatedKey']['HashKeyElement']['S'])
        print "Capacity: " + str(results['ConsumedCapacityUnits'])
        print "Loop Iterations: " + str(loop_iterations)

    return total_results
以及我的输出:

Count: 96
Scanned Count: 96
Last Evaluated Key: kBR23QJNAwYZZxF4E3N1crQuaTwjIeFfjIv8NyimI9o
Capacity: 517.5
Loop Iterations: 1
Count: 109
Scanned Count: 109
Last Evaluated Key: ATcJFKfY62NIjTYY24Z95Bd7xgeA1PLXAw3gH0KvUjY
Capacity: 516.5
Loop Iterations: 2
Count: 104
Scanned Count: 104
Last Evaluated Key: Lm3nHyW1KMXtMXNtOSpAi654DSpdwV7dnzezAxApAJg
Capacity: 516.0
Loop Iterations: 3
Count: 104
Scanned Count: 104
Last Evaluated Key: iirRBTPv9xDcqUVOAbntrmYB0PDRmn5MCDxdA6Nlpds
Capacity: 513.0
Loop Iterations: 4
Count: 100
Scanned Count: 100
Last Evaluated Key: nBUc1LHlPPELGifGuTSqPNfBxF9umymKjCCp7A7XWXY
Capacity: 516.5
Loop Iterations: 5
这是预期的行为吗?或者,我做错了什么?

简短回答 你没有做错什么

长话短说 这与Amazon计算容量单位的方式密切相关。首先,非常重要的是要了解:

  • 容量单位==保留的计算单位
  • 容量单位!=预留网络传输
嗯,即使严格来说这也不确切,但非常接近,尤其是在
扫描方面

扫描
操作期间,以下各项之间有一个基本区别

  • 扫描项目:累积大小最多为1MB,如果已达到
    限制
    ,则可能低于该大小
  • 返回的项目:在扫描项目中匹配的所有项目
由于
容量单位
是一个计算单位,因此您可以扫描的项目支付。嗯,实际上,你要支付扫描项目的累计大小。请注意,此大小包括所有存储和索引开销<代码>0.5容量/累计KB

扫描的大小不依赖于任何过滤器,无论是字段选择器还是结果过滤器

从您的结果来看,我猜您的项目每个都需要~10KB,您对其实际有效负载大小的评论倾向于证实这一点

另一个例子
我有一个测试表,它只包含非常小的元素。扫描仅消耗
1.0
容量单位来检索100个项目,因为
累积大小<2KB

您的项目有多大?你能提供一个样品吗?每件都是6kb大小。我注意到,无论是指定要获取的属性,还是获取所有内容,使用的读取容量都是相同的。这是一个好问题,因为它照亮了DynamoDB内部的一些黑暗方面。
Count: 96
Scanned Count: 96
Last Evaluated Key: kBR23QJNAwYZZxF4E3N1crQuaTwjIeFfjIv8NyimI9o
Capacity: 517.5
Loop Iterations: 1
Count: 109
Scanned Count: 109
Last Evaluated Key: ATcJFKfY62NIjTYY24Z95Bd7xgeA1PLXAw3gH0KvUjY
Capacity: 516.5
Loop Iterations: 2
Count: 104
Scanned Count: 104
Last Evaluated Key: Lm3nHyW1KMXtMXNtOSpAi654DSpdwV7dnzezAxApAJg
Capacity: 516.0
Loop Iterations: 3
Count: 104
Scanned Count: 104
Last Evaluated Key: iirRBTPv9xDcqUVOAbntrmYB0PDRmn5MCDxdA6Nlpds
Capacity: 513.0
Loop Iterations: 4
Count: 100
Scanned Count: 100
Last Evaluated Key: nBUc1LHlPPELGifGuTSqPNfBxF9umymKjCCp7A7XWXY
Capacity: 516.5
Loop Iterations: 5