我正在编写一个Web应用程序,它将使用Django 1.6和PostgreSQL 9.1显示在线游戏的玩家统计数据。我使用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 ...或name [25000]'。 :)
答案 0 :(得分:0)
如果您想减少查询次数,我建议: 直接为每个玩家调用update(),返回更新的行数,如果计数为0(表示玩家是新的),则将玩家数据放入临时列表中。完成所有获取的播放器后,使用bulk_create()通过一个SQL语句插入所有新播放器。
假设您有M + N个玩家(M new,N更新),查询次数:
之前:(M + N)选择+ M次插入+ N次更新
之后:(M + N)更新+1批量插入。