使用php将数百万条记录插入sql server的快速方法


fast way to insert millions record into sql server using php

我有一个2000000行的文本文件,希望将每一行插入数据库行,因此,使用php文件将2000000条记录插入到sql server中。最快的方法是什么?

为了测试,我使用了以下代码:

for ( $i=1 ; $i<=2000000 ; $i++)
    {
        $sql = "INSERT INTO BlastSequenceDim (Seq_id) VALUES ('$i')";
        $stmt = sqlsrv_query( $conn, $sql);
        if( $stmt === false ) 
        {
            die( print_r( sqlsrv_errors(), true));
        }
    }

但是,这需要很多时间。这个查询能在几秒钟内执行吗?

谢谢,

请使用批量插入,这将显著提高性能并节省时间。

了解有关SQL 中批量插入查询的更多信息

您还可以通过省去PHP并直接访问SQL数据库来节省时间,这将是最初填充数据库的常见做法。

另一个链接

而不是单独运行每个查询。将查询连接在一起,然后一次运行所有查询。

for ( $i=1 ; $i<=2000000 ; $i++)
{
    $sql .= "INSERT INTO BlastSequenceDim (Seq_id) VALUES ('$i');";
}
$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false ) 
{
    die( print_r( sqlsrv_errors(), true));
}

通常瓶颈是PHP没有运行多线程。这意味着在您的情况下,一个进程按顺序读取文件并逐行插入,即使您的服务器/PC有8个或更多核心。

我遇到了同样的问题,我必须在memcache键中插入很多值,我用php-phread解决了这个问题。

这肯定是更多的工作,但当它是一个重复的任务时(就像我的情况一样),那么用pthread实现它肯定是值得的。

作为提示,我建议启动的线程总数不应大于number_of_cpu_coresx 1.5。

只有一个问题:如何协调从文本文件中读取。在这里,我会考虑将两个数字传递给每个线程:

  • 从行号X开始
  • 为跳过其他线程读取的行而添加到X中的偏移量

您会对性能的提高感到惊讶!将它与你的问题的其他答案相结合,它将是无与伦比的。。。

实现这一点的一种方法是将整个数据集编码为JSON,并在单个查询中发送。有几种不同的方法可以实现这一点。微软文档在这里讨论一个。他们在示例中插入JSON对象(因此,如果您想批量执行,您可以使用对象数组)。

我将使用一个数组。这使得SQL的可读性略低,但减少了开销。此外,我正在通过PDO访问MSSQL,但您可以同样轻松地使用sqlsrv。

$stmt = $db->prepare(<<<EndSQL
CREATE TABLE #exampleTable (
    A VARCHAR(200),
    B VARCHAR(200)
)
INSERT INTO #exampleTable
SELECT * FROM OPENJSON(?) WITH (
    A VARCHAR(200) '$[0]',
    B VARCHAR(200) '$[1]'
);
DROP TABLE #exampleTable;
EndSQL);
$data = [];
for($i = 0; $i < 100000; $i++) {
    $data[] = [
        'A' => 'A-val-' . $i,
        'B' => 'B-val-' . $i
    ];
}
$stmt->execute([json_encode($data)]);

这类似于在同一条语句中插入一堆插入语句的策略,但它允许您使用静态SQL语句,而不管您有多少插入语句。

INSERT INTO #exampleTable VALUES
(?, ?),
(?, ?),
(?, ?),
(?, ?),
(?, ?),
(?, ?),
(?, ?),
...

如果你确实使用了这个,那么你可能遇到的下一个限制就是内存。这会在将所有内容发送到SQL之前将其加载到PHP的内存中。有两种方法可以解决这个问题:批量处理约10000行,或者在生成JSON时将其流式传输到SQL Server。