Python函数生成了太多的数据库更新

时间:2014-05-09 17:08:42

标签: python postgresql

这里有点令人费解。

我有一个数据库表,其中包含一组统计信息作为列,一组非常相似的平均值。

设置一个函数来迭代我的数据集非常容易,并且多次更新数据库中的行。

但它的速度非常慢而且只需要进行一次更新的大型长脚本需要花费大量的时间来编写,并且很难维护。

我想知道是否有办法以某种方式既是OOP又不是那么多冗余寻求/数字运算。

我想知道是否有更简单的方法...... SSIS会让我只抽取一次数据,最后将其合并,然后将其重新输入数据库。但我不确定如何用Python做到这一点......

所以我在python中定义了一个平均n天的函数:

def moving_average(conn, cur, dates, days, stockid, col_name):
#    print days
    if (len(dates) < days):
        print "WARNING: Cannot do a " + str(days) + " day moving average for stock id " + str(stock_id) + "!  Not enough data!"
    else:
        for x in range (0, len(dates) - int(days) - 1):
            row_id = dates[x][0]
            numerator = 0
            for i in range (0, days - 1):
                numerator = numerator + dates[x][3]
                moving_average_for_period = round(numerator / days, 2)
                sql = "UPDATE historical_prices SET " + col_name + " = " + str(moving_average_for_period) + " WHERE id = " + str(row_id) + ";"
                cur.execute(sql) 
        conn.commit()

到目前为止一切顺利。

然后我打电话给:

  # now do the moving averages
    moving_average(conn,cur,dates,5,stock_id,'five_day_ma')
    moving_average(conn,cur,dates,10,stock_id,'ten_day_ma')
    moving_average(conn,cur,dates,15,stock_id,'fifteen_day_ma')
    moving_average(conn,cur,dates,30,stock_id,'thirty_day_ma')
    moving_average(conn,cur,dates,60,stock_id,'sixty_day_ma')
    moving_average(conn,cur,dates,120,stock_id,'onetwenty_day_ma')

看我的问题?我做我的I / O 6x。

提前感谢您的帮助。

干杯,

1 个答案:

答案 0 :(得分:0)

虽然纯SQL通常比来自Python(或Java等)的一次更新更快,但在大型表中执行UPDATE会根据其大小迅速变为指数级缓慢,即使对于相对较小的数量正在更新的行。

如果你选择纯SQL路由(我的意思是从Python做一个影响大量行的UPDATE) - 我肯定会在这种情况下推荐这种方法 - 我会建议使用LIMITOFFSET对其进行分块,以使每个UPDATE小得多。 Postgres经常能够更好地处理。 (我曾经有过这样的情况:UPDATE在一个块中完成后不会在一个块中完成,并且在30分钟内完成(通过Python)以5000块为单位完成。

当然,如果你的桌子足够小,你可能不会遇到这个问题,但要注意这一点。