【问题标题】:Implement batch insert to improve performance实施批量插入以提高性能
【发布时间】:2015-10-14 07:00:42
【问题描述】:

我已经编写了以下代码来将数据插入到 MEMSql 中,它的语法与 MySQL 中的语法几乎相似。

def get_connection(db=DATABASE):
    """ Returns a new connection to the database. """
    return database.connect(host=HOST, port=PORT, user=USER, password=PASSWORD, database=db)



def insert_data(data):
    print 'inserting data...'

    for item in data:
        vars_to_sql = []
        keys_to_sql = []
        print(item)
        for key,value in item.iteritems():
             if key == '__osHeaders':
                value = str(value)
             if isinstance(value, unicode):
                vars_to_sql.append(value.encode('ascii', 'ignore'))
                keys_to_sql.append(key.encode('ascii', 'ignore'))
             else:
                vars_to_sql.append(value)
                keys_to_sql.append(key)

        keys_to_sql = ', '.join(keys_to_sql)
        with get_connection() as conn:

             c = conn.execute("INSERT INTO tablename (%s) VALUES %r" % (keys_to_sql,  tuple(vars_to_sql),))
             print c

字段名称不能硬编码,因为它们可能会根据我从另一端获得的数据而改变。无论如何,它是我在这里迭代的字典。由于这个单次插入非常慢,我需要将批量大小作为变量,形成查询语句并相应地插入。所以批量大小为 2 的查询将是 INSERT INTO tablename col1, col2 VALUES ('a', 'b'),('c','d')

请帮我在这里介绍一下。

【问题讨论】:

  • 第二个没有指定字段。第一个我需要获取我需要并执行的数据的副本。为什么我不能在我拥有的同一个字典中这样做
  • 在第二个中,在VALUES之前插入你的col1, col2
  • 或者这也改变了? (这实际上可能是您问题的重点)

标签: python batch-insert singlestore


【解决方案1】:

如果您使用的是 MemSQL Python 库,则可以使用 memsql.common.query_builder 包中提供的 multi_insert 帮助程序。例如:

from memsql.common.query_builder import multi_insert
from memsql.common.database import connect

sql, params = multi_insert("my_table", { "foo": 1 }, { "foo": 2 })
# sql = 'INSERT INTO `my_table` (`foo`) VALUES (%(_QB_ROW_0)s), (%(_QB_ROW_1)s)'
# params = {'_QB_ROW_0': [1], '_QB_ROW_1': [2]}

with connect(...) as conn:
    conn.execute(sql, **params)

请注意,multi_insert 要求每条记录都定义相同的列集,因为它将查询转换为基于元组的插入。

【讨论】:

  • 操作:Fieldnames also change which I use keys_to_sql to define them。你的答案:Note that multi_insert requires that each record has the same set of columns 所以我认为这不会解决问题
  • 但你有一个好点:multi_insert 似乎是 memsql 的bulk_insert!只需要检查它是否接受DEFAULT 值:-)
  • 我得到了一个 Json 字符串,我将它转换为字典列表[{ "foo": 1 }, { "foo": 2 }] using json.loads() 那么我应该如何从中输入这个函数multi_insert()
  • 可能有一些unpacking,比如multi_insert("my_table", *json_list)
  • @CarlSverre 感谢您使用 Memsql-python 库提供答案,我成功实现了该库,更改很少且性能良好。为你 +1。
【解决方案2】:

以下答案可能对您有所帮助:https://stackoverflow.com/a/8777776/3207406

  1. 您可以拥有一个元组,其中包含可能在某个时候使用的所有列
  2. 使用您要插入的实际值创建一个元组列表,并使用 DEFAULT 默认值,
  3. 然后bulk-insert他们

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多