Python MS Access数据库中的PYODBC Insert语句速度极慢

Python MS Access数据库中的PYODBC Insert语句速度极慢,python,performance,ms-access,sql-insert,pyodbc,Python,Performance,Ms Access,Sql Insert,Pyodbc,我希望加快我的insert语句进入Access数据库的速度。数据仅为86500条记录,需要24小时才能处理。我希望加快的代码部分是比较两个表的重复项。如果未找到重复项,则插入该行。我正在运行64位windows 10、32位python 2.7、32位ms access odbc驱动程序和32位pyodbc模块。如有任何帮助,将不胜感激。下面是代码示例 def importDIDsACC(): """Compare the Ledger to ImportDids to find any

我希望加快我的insert语句进入Access数据库的速度。数据仅为86500条记录,需要24小时才能处理。我希望加快的代码部分是比较两个表的重复项。如果未找到重复项,则插入该行。我正在运行64位windows 10、32位python 2.7、32位ms access odbc驱动程序和32位pyodbc模块。如有任何帮助,将不胜感激。下面是代码示例

def importDIDsACC():
    """Compare the Ledger to ImportDids to find any missing records"""
    imdidsLst = []
    ldgrLst = readMSAccess("ActivityNumber", "Ledger")
    for x in readMSAccess("DISP_NUM", "ImportDids"):
        if x not in ldgrLst and x not in imdidsLst:
            didsLst.append(x)
    #Select the records to import
    if len(imdidsLst) > 0:
        sql = ""
        for row in imdidsLst:
            sql += "DISP_NUM = '" + row[0]
            cursor.execute("SELECT * FROM ImportDids WHERE " + sql)
            rows = cursor.fetchall()
            #Import to Ledger
            dupChk = []
            for row in rows:
                if row[4] not in dupChk:
                    cursor.execute('INSERT into Ledger ([ActivityNumber], [WorkArea], [ClientName], [SurfacePurpose], [OpsApsDist], [AppDate], [LOADate], [EffDate], [AmnDate], [CanDate], [RenDate], [ExpDate], [ReiDate], [AmlDate], [DispType], [TRM], [Section], [Quarter], [Inspected_Date], [Inspection_Reason], [Inspected_By], [InspectionStatus], [REGION], [DOC], [STATCD]) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
                                   str(row[1]), str(row[18]), str(row[17]), row[14], str(row[26]), row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], str(row[1][0:3]), trmCal(str(row[21]),str(row[20]), str(row[19])), str(row[22]), str(row[23]), inspSts(str(row[1]), 0),inspSts(str(row[1]), 1), inspSts(str(row[1]), 2), inspSts(str(row[1]), 3), str(row[27]), str(row[3]), str(row[13]))
                    dupChk.append(row[4])
            cnxn.commit()

def readMSAccess(columns, table):
    """Select all records from the chosen field"""
    sql = "SELECT "+ columns +  " FROM " + table
    cursor.execute(sql)
    rows = cursor.fetchall()
    return rows

def dbConn():
    """Connects to Access dataBase"""
    connStr = """
    DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};
    DBQ=""" + getDatabasepath() + ";"
    cnxn = pyodbc.connect(connStr)
    cursor = cnxn.cursor()
    return cursor, cnxn

def getDatabasepath():
    """get the path to the access database"""
    mycwd = os.getcwd()
    os.chdir("..")
    dataBasePath = os.getcwd() + os.sep + "LandsAccessTool.accdb"
    os.chdir(mycwd)
    return dataBasePath

# Connect to the Access Database
cursor, cnxn = dbConn()

# Update the Ledger with any new records from importDids
importDIDsACC()

不要使用外部代码检查重复项。数据库(甚至Access)的功能是最大化其数据集操作。不要试图重写那种代码,尤其是因为你发现它效率不高。相反,将所有内容导入临时数据库表,然后使用Access(或适当的Access数据引擎)执行SQL语句来比较表,查找或排除重复的行。然后,这些查询的结果可以用于创建和/或更新其他表——所有这些都在数据库引擎的上下文中。当然,使用适当的索引和键设置临时表以最大限度地提高效率


同时,在本地比较数据集(即表)时,从单个数据库请求(即SQL SELECT语句)将所有值加载到某个可搜索的集合中,然后使用该内存集合搜索匹配项,通常会更快(我是否可以说始终?)。在我上一次关于最大化数据库功能的发言之后,这似乎很讽刺,但重要的是理解数据集作为一个整体是如何处理的。在python进程和数据库引擎之间来回传输数据,即使数据在同一台机器上,也要比处理python进程中的所有内容或数据库引擎进程中的所有内容慢得多。唯一一次可能没有用的是当远程数据集太大而无法下载时,但87000个键值肯定小到足以将所有值加载到python集合中。

您可以在这里找到更好的方法(Gord Thompson的建议):