Postgres的快速数组插入

时间:2012-05-11 07:55:53

标签: postgresql

在Oracle OCI和OCCI中,有一些API工具可以执行数组插入,您可以在客户端中构建值数组,并将此数组与准备好的语句一起发送到服务器,以便将数千个条目插入到单个表中在某些情况下,镜头会带来巨大的性能提升。 PostgreSQL中有类似的内容吗?

我正在使用PostgreSQL C API库存。

一些伪代码来说明我的想法:

stmt = con->prepare("INSERT INTO mytable VALUES ($1, $2, $3)");
pg_c_api_array arr(stmt);
for triplet(a, b, c) in mylongarray:
    pg_c_api_variant var = arr.add();
    var.bind(1, a);
    var.bind(2, b);
    var.bind(3, c);
stmt->bindarray(arr);
stmt->exec()

3 个答案:

答案 0 :(得分:3)

PostgreSQL具有类似的功能 - 声明COPY和COPY API - 它非常快

libpq documentation

char *data = "10\t20\40\n20\t30\t40";

pres = PQexec(pconn, "COPY mytable FROM stdin");

/* can be call repeatedly */ 
copy_result = PQputCopyData(pconn, data, sizeof(data));
if (copy_result != 1)
{
        fprintf(stderr, "Copy to target table failed: %s\n",
                                        PQerrorMessage(pconn));
        EXIT;
}

if (PQputCopyEnd(pconn, NULL) == -1)
{
         fprintf(stderr, "Copy to target table failed: %s\n",
                                            PQerrorMessage(pconn));
                            EXIT;
}

pres = PQgetResult(pconn);
if (PQresultStatus(pres) != PGRES_COMMAND_OK)
{
       fprintf(stderr, "Copy to target table failed:%s\n",
                                            PQerrorMessage(pconn));
           EXIT;
}

PQclear(pres);

答案 1 :(得分:1)

正如Pavel Stehule指出的那样,有一个COPY命令,当在C中使用libpq时,相关函数用于传输复制数据。我没有用过这些。我主要针对Python中的PostgreSQL编程,已经使用了psycopg2的类似功能。这非常简单:

conn = psycopg2.connect(CONN_STR)
cursor = conn.cursor()
f = open('data.tsv')
cusor.copy_from(f, 'incoming')
f.close()

事实上,我经常用一个类似文件的包装器对象替换open,该对象先执行一些基本的数据清理。它非常无缝。

答案 2 :(得分:1)

我喜欢这种在一个命令中创建数千行的方法:

INSERT INTO mytable VALUES (UNNEST($1), UNNEST($2), UNNEST($3));

将第1列的值数组绑定到$1,将第2列的值数组绑定到$2等等!当你习惯于在行中思考时,在列中提供值可能看起来有点奇怪。

UNNEST或者您自己的函数需要PostgreSQL> = 8.4才能将数组转换为集合。