1

我正在使用 Django 1.6 和 PostgreSQL 9.1 编写一个 Web 应用程序,它将显示在线游戏的玩家统计信息。我使用 django-extensions “runscript” 创建了一个脚本,该脚本获取所有在线玩家并将其插入/更新到我的表中。该脚本使用 cron 每小时执行 4 次。我需要插入或更新,因为播放器可能已经在表中(因此应该更新)或不在表中。

对于我的问题:高峰时段大约有 25,000 名玩家在线,我不确定我应该如何优化这一点(最小化 hdd i/o)。这就是我到目前为止所做的:

@transaction.commit_manually
def run():
    for fetched_player in FetchPlayers():
        defaults = {
            'level': fetched_player['level'],
            'server': fetched_player['server'],
            'last_seen': date.today(),
        }
        player, created = Player.objects.get_or_create(name=fetched_player['name'], defaults)
        if not created:
            player.level = fetched_player['level']
            if player.server != fetched_player['server']:
                # I save this info to another table
            player.server = fetched_player['server']
            player.last_seen = date.today()
            player.save()
    transaction.commit()

绕过 Django 并使用 psycopg2 或类似工具访问数据库会更快吗?当“其他人”修改数据库时,Django 会感到困惑吗?请注意,Django 仅读取数据库,所有写入均由该脚本完成。

如何(使用 Django 或 psycopg2)从数据库中批量获取播放器,更新找到的播放器,然后插入未找到的播放器?如果这甚至可能?查询会变得很大:'SELECT * FROM player WHERE name = name[0] OR name = name[1] OR ... OR name[25000]'。:)

4

1 回答 1

1

如果要减少查询次数,我的建议是:直接为每个播放器调用update(),返回更新的行数,如果计数为0(表示播放器是新的),放播放器数据在临时列表中。完成所有获取的播放器后,使用 bulk_create() 通过一条 SQL 语句插入所有新播放器。

假设你有 M+N 玩家(M 新,N 更新),查询次数:

之前:(M+N) 选择 + M 插入 + N 更新

之后:(M+N) 次更新 + 1 次批量插入。

于 2014-03-15T03:52:35.167 回答