Django质量更新/插入性能

时间:2018-05-01 07:06:35

标签: django python-3.x django-models django-database

我每5秒钟收到大约5000台仪器的财务数据,需要更新数据库中的相应条目。该模型如下所示:

class Market(models.Model):
    market = models.CharField(max_length=200)
    exchange = models.ForeignKey(Exchange,on_delete=models.CASCADE) 
    ask = models.FloatField()
    bid = models.FloatField()
    lastUpdate = models.DateTimeField(default = timezone.now)

需要做的是:

  • 收到新的财务数据后,检查是否存在条目 数据库。
  • 如果条目存在,请更新ask,bid和lastUpdate字段
  • 如果该条目不存在,请创建一个新条目

我的代码如下:

bi_markets = []
for item in dbMarkets:
    eItem = Market.objects.filter(exchange=item.exchange,market=item.market)
    if len(eItem) > 0:
        eItem.update(ask=item.ask,bid=item.bid)
    else:
        bi_markets.append(item)

#Bulk insert items that does not exist
Market.objects.bulk_create(bi_markets)  

然而执行此操作需要太长时间。大约30秒。我需要将时间缩短到1秒。我知道这可以完成,因为我在100ms内在.NET中使用相同的自定义SQL代码。知道如何提高Django的性能吗?

2 个答案:

答案 0 :(得分:1)

如果这是你想要的这种性能,我不明白为什么你不会突破原始SQL。批量创建不存在的东西但听起来像是Django并不是真正为之做的高级SQL查询。

https://docs.djangoproject.com/en/2.0/topics/db/sql/

您也可以(手机上抱歉):

bi_markets = []
for item in dbMarkets:
  rows = Market.objects.filter(exchange=item.exchange, market=item.market).update(ask=item.ask, bid=item.bid)
  if rows == 0:
    bi_markets.append(item)

Market.objects.bulk_create(bi_markets)

也许这个组合会生成一些更好的SQL,并且它也会回避exists()调用(update返回它改变了多少行。)

答案 1 :(得分:0)

我决定拆分更新并创建功能。创建仅在应用程序启动时发生,从那里我使用自定义SQL脚本进行更新。见下文。工作得很好。

updateQ = []
updateQ.append("BEGIN TRANSACTION;")

for dbItem in dbMarkets:
    eItem = tickers[dbItem.market]
    qStr = "UPDATE app_market SET ask = " + str(eItem['ask']) + ",bid = " + str(eItem['bid']) + " WHERE exchange_id = " + str(e.dbExchange.pk) + " AND market = " + '"' + dbItem.market + '";'
    updateQ.append(qStr)

updateQ.append("COMMIT;")

updateQFinal  = ''.join(map(str, updateQ))

with connection.cursor() as cursor:
    cursor.executescript(updateQFinal)