postgres INSERT命令的速度提升

时间:2016-09-30 02:19:56

标签: python postgresql psycopg2

我正在编写一个程序来将数据加载到特定的数据库中。这就是我现在正在做的事情......

        conn = psycopg2.connect("dbname='%s' user='postgres' host='localhost'"%dbName)
        cur  = conn.cursor()

        lRows = len(rows)
        i, iN = 0, 1000
        while True:

            if iN >= lRows:
                # write the last of the data, and break ...
                iN = lRows
                values = [dict(zip(header, r)) for r in rows[i:iN]]
                cur.executemany( insertString, values )
                conn.commit()
                break

            values = [dict(zip(header, r)) for r in rows[i:iN]]
            cur.executemany( insertString, values )
            conn.commit()

            i  += 1000
            iN += 1000

        cur.close()
        conn.close()

我知道有关使用COPY命令的this问题。但是,在将文件上传到数据库之前,我需要对文件进行一些记录。因此我以这种方式使用Python。

关于如何让事情更快,我有几个问题......

  1. 在最后做一些cur.executemany()语句和一个conn.commit()会更好(或可能)吗?这意味着我将在conn.commit()语句之前放置一个 cur.close()语句。
  2. 我一直看到其他人使用cur.executemany()批量大约1000个左右的记录。这通常是这种情况,还是可以在我从文件中读取的整个记录​​集上执行cur.executemany()。我可能会有数十万条记录,或者可能有一百多万条记录。 (我有足够的RAM来使整个文件适合内存)。我如何知道我一次可以上传的记录数量的上限。
  3. 我正在为我打开的每个文件建立一个与数据库的新连接。我这样做是因为,这个过程需要很多天才能完成,如果连接在任何时候丢失,我不希望连接问题破坏整个数据。我有超过一千个文件需要经历。我们正在进行的这千个连接是否是用于该过程的时间的重要部分?
  4. 我在程序中还有其他任何我不应该做的事情可以缩短整个过程的总时间吗?
  5. 非常感谢我能得到的任何帮助。对不起,问题是如此基本。我刚刚开始使用Python中的数据库,出于某种原因,我现在似乎对这些问题没有任何明确的答案。

1 个答案:

答案 0 :(得分:1)

  1. 正如您在第3页中提到的,您担心数据库连接可能会中断,因此如果仅在所有插入后使用一个conn.commit(),则可以轻松地松开已插入但未提交的数据如果您的连接在conn.commit()之前中断如果您在conn.commit()之后cur.executemany() cur.executemany(),则不会丢失所有内容,只会丢失最后一批。因此,它取决于您,并取决于您需要支持的工作流程。

  2. 每批记录的数量是插入速度和其他内容之间的权衡。您需要选择满足您要求的值,您可以测试您的脚本每批1000个记录,每批10000个并检查差异。 在一个COPY TO中插入整个文件的情况具有原子性的优点:如果已经执行,则表示已插入来自该特定文件的所有记录,因此我们返回到p。 1。

  3. 我认为在您的案例中建立新连接的成本并不重要。让我们说,如果需要一秒钟来建立新连接,那么在1000天内,连接花费的时间将是1000秒。

  4. 程序本身看起来不错,但我仍然建议您使用UNLOGGEDTEMPORARY表来查看> <DOCTYPE html> > > <html lang="en"> > > <head> <link rel="stylesheet" type="text/css" href="test.css"> > <title>KDU Music</title> <meta charset="utf-8"> </head> > > > <body> <div id="title"> > <p><h1>Welcome to KDU MUSIC CENTER</h1></p> > </div> > > > <div id= "wrapper"> <div id="nav"> <ul> > <li><a href="index.html">Home</a></li> > <li><a href="findoutmore.php">Find out more</a></li> > <li><a href="offer.html">Offer</a></li> > <li><a href="credit.html">Credit</a></li> > <li><a href="#">Admin</a></li> > <li><a href="wireframe.html">WireFrame</a></li> </ul> </div> > > <div id="content"> > > <div class = "first"> <p><h1>123</h1></p> <p><h1>123</h1></p> > <p><h1>123</h1></p> <p><h1>123</h1></p> </div> <div class = > "first"> > <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> > </div> > <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> > <p><h1>123</h1></p> <p><h1>123</h1></p> <p><h1>123</h1></p> > <p><h1>123</h1></p> <p><h1>123</h1></p> > > </div> </div> > > </body> > > </html> 命令,它会真正加快您的导入速度