Python pymssql executemany插入值非常慢

Python pymssql executemany插入值非常慢,python,sql-server-2012,pymssql,executemany,Python,Sql Server 2012,Pymssql,Executemany,python-2.7.15、pymssql-2.1.4、SQL_Server-2018、Windows 10 Pro、MS-Office-2016 import time import csv import pymssql db_settings = { "host" : "127.0.0.1", "port" : "1433", "user" : "sa", "password" : "********", "database" : "testdb",

python-2.7.15、pymssql-2.1.4、SQL_Server-2018、Windows 10 Pro、MS-Office-2016

import time
import csv
import pymssql

db_settings = {
    "host" : "127.0.0.1",
    "port" : "1433",
    "user" : "sa",
    "password" : "********",
    "database" : "testdb",
    "charset" : "utf8"
               }
conn = pymssql.connect(**db_settings)
cursor = conn.cursor()
ff = csv.reader(open('base.csv', 'r'))
sql = """
    BEGIN
        INSERT INTO Base([name], [year], [update], [status], 
    [timeline], [language], [pic]) VALUES (%s, %s, %s, %s, %s, %s, %s)
    END
    """
now=time.strftime("%M:%S")
t = []
for i in ff:
    i = i[1:]
    if "year" in i:
        pass
    else:
        t.append((i[0], i[1], i[3], i[4], i[6], i[5], i[8]))
cursor.executemany(sql, t)
conn.commit()

end=time.strftime("%M:%S")

print(now+","+end)
“base.csv”文件大小为21.7 MB,共30374行。当我执行上述代码时,需要929秒才能完成。这意味着只有32.7行/秒,速度太慢了。谁能帮我找出原因?非常感谢。:-)


我将pymssql中的许多执行时间从30分钟减少到30秒,就像这样

在sql中,您可以一次创建包含多行的insert语句。它看起来像下面

INSERT (col_name1, col_name2) 
INTO table_name 
VALUES 
(row1_val1, row1_val2), 
(row2_val1, row2_val2) ... 
(row1000_val1, row1000_val2)
我实现了insert函数,该函数获取数据块,并修改查询以在一次执行中插入多个值

def insert(query, data, chunk=999):
    conn = get_connection()
    cursor = conn.cursor()
    query = query.lower()
    insert_q, values_q = query.split('values') # get part with the query and the parameters
    insert_q += 'values' # add values to make sql query correct after split
    for chunk_data in chunks(data, chunk):
        # chunk_data contains list of row parameters
        flat_list = [item for sublist in chunk_data for item in sublist] # we make it flat to use execute later instead execute_many
        chunk_query = insert_q + ','.join([values_q] * len(chunk_data)) # creating the query with multiple values insert
        cursor.execute(chunk_query, tuple(flat_list)
        conn.commit()
可以像这样实现(多亏了本论坛上的精彩回复)

示例用法

insert('INSERT (user_id, name, surname) INTO users VALUES (%s, %s, %s)',
       [(1, 'Jack', 'Kcaj'), (2, 'Andrew', 'Golara')]

我将pymssql中的许多执行时间从30分钟减少到30秒,如下所示

在sql中,您可以一次创建包含多行的insert语句。它看起来像下面

INSERT (col_name1, col_name2) 
INTO table_name 
VALUES 
(row1_val1, row1_val2), 
(row2_val1, row2_val2) ... 
(row1000_val1, row1000_val2)
我实现了insert函数,该函数获取数据块,并修改查询以在一次执行中插入多个值

def insert(query, data, chunk=999):
    conn = get_connection()
    cursor = conn.cursor()
    query = query.lower()
    insert_q, values_q = query.split('values') # get part with the query and the parameters
    insert_q += 'values' # add values to make sql query correct after split
    for chunk_data in chunks(data, chunk):
        # chunk_data contains list of row parameters
        flat_list = [item for sublist in chunk_data for item in sublist] # we make it flat to use execute later instead execute_many
        chunk_query = insert_q + ','.join([values_q] * len(chunk_data)) # creating the query with multiple values insert
        cursor.execute(chunk_query, tuple(flat_list)
        conn.commit()
可以像这样实现(多亏了本论坛上的精彩回复)

示例用法

insert('INSERT (user_id, name, surname) INTO users VALUES (%s, %s, %s)',
       [(1, 'Jack', 'Kcaj'), (2, 'Andrew', 'Golara')]

在for循环检查年份后,是否可以插入另一份时间打印?我怀疑不是插入花费了这么长的时间,而是字符串比较…我试图在代码中删除for循环,这需要928秒,for循环只想删除base.csvHm中的第一行。。。csv是保密的还是您可以在此处共享该数据?我想自己尝试一下代码,但是在没有原始数据的情况下这样做可能会产生非常不同的结果。在进入ff:循环中的I之前,可以使用
next(ff,None)
跳过标题行。这样,您就不必检查后续的每一行。您是否真的要插入本地数据库实例(127.0.0.1)?当我对100000行x 4列执行此操作时,我使用pymssql获得大约695行/秒(使用pyodbc获得大约5000行/秒,“SQL Server的ODBC驱动程序17”和
fast_executemany=True
)(cc:@sekky)-我刚刚再次尝试使用您的30374行测试数据。我使用pymssql每秒获得2336行,使用pyodbc+fast_ExecuteMy每秒获得7594行。很明显,在您的环境中还有其他一些您没有展示给我们的东西。您能在for循环检查年份之后插入另一个时间打印吗?我怀疑不是插入花费了这么长的时间,而是字符串比较…我试图在代码中删除for循环,这需要928秒,for循环只想删除base.csvHm中的第一行。。。csv是保密的还是您可以在此处共享该数据?我想自己尝试一下代码,但是在没有原始数据的情况下这样做可能会产生非常不同的结果。在进入ff:循环中的I之前,可以使用
next(ff,None)
跳过标题行。这样,您就不必检查后续的每一行。您是否真的要插入本地数据库实例(127.0.0.1)?当我对100000行x 4列执行此操作时,我使用pymssql获得大约695行/秒(使用pyodbc获得大约5000行/秒,“SQL Server的ODBC驱动程序17”和
fast_executemany=True
)(cc:@sekky)-我刚刚再次尝试使用您的30374行测试数据。我使用pymssql每秒获得2336行,使用pyodbc+fast_ExecuteMy每秒获得7594行。很明显,在你的环境中还有一些你没有展示给我们的东西。