代码之家  ›  专栏  ›  技术社区  ›  LtPinback

如何提高包含作为条件的sqlachemy查询语句的循环的速度

  •  4
  • LtPinback  · 技术社区  · 15 年前

    此循环检查记录是否在sqlite数据库中,并为丢失的记录生成字典列表,然后使用该列表执行多个insert语句。这是可行的,但它非常慢(至少我认为它很慢),因为循环3500个查询需要5分钟。我对python、sqlite和sqlacalchemy都是个新手,所以我想知道是否有更快的方法可以做到这一点。

    list_dict = []
    
    session = Session()
    
    for data in data_list:
        if session.query(Class_object).filter(Class_object.column_name_01 == data[2]).filter(Class_object.column_name_00 == an_id).count() == 0:
            list_dict.append({'column_name_00':a_id,
                              'column_name_01':data[2]})
    
    conn = engine.connect()
    conn.execute(prices.insert(),list_dict)
    conn.close()
    session.close()
    

    编辑:我搬家了 session = Session() 在环外。没什么区别。

    解决方案 :

    多亏了 麦克拉尔 答:我将代码修改为:

    existing_record_list = []
    list_dict = []
    
    conn = engine.connect()
    s = select([prices.c.column_name_01], prices.c.column_name_00==a_id)
    result = conn.execute(s) 
    for row in result:       
        existing_record_list.append(row[0])
    
    for data in raw_data['data']:
        if data[2] not in existing_record_list:
            list_dict.append({'column_name_00':a_id,
                              'column_name_01':data[2]}
    
    conn = engine.connect()
    conn.execute(prices.insert(),list_dict)
    conn.close()
    

    现在需要6秒钟。这是一些改进!!

    2 回复  |  直到 12 年前
        1
  •  3
  •   mcabral    15 年前

    3500个查询似乎是一个很大的数字,

    是否考虑在一个查询中提取所有实体?然后您将在内存中迭代一个列表,而不是查询每个项目的数据库。

        2
  •  0
  •   InsanelyADHD    12 年前

    很高兴你找到了一些有用的东西,作为额外的2美分:

    我同意麦卡布拉的观点。作为一般规则,如果您将查询放入循环中,那么您就是在自找麻烦。流行的SQL数据库通常针对数据采集进行了优化。循环查询通常表示您正在按程序执行一些应该/可以使用单个查询或字符串(将数据放入彼此中的查询)执行的操作。

    这也有例外,但根据我的经验,他们通常很少,而且还远远没有……每次我通过一个循环运行一个查询时,我都会后悔。