Sql server 如何在不使节点崩溃的情况下从SQL Server流式传输200万行?

Sql server 如何在不使节点崩溃的情况下从SQL Server流式传输200万行?,sql-server,node.js,stream,Sql Server,Node.js,Stream,我使用Node将200万行从SQL Server复制到另一个数据库,因此我当然使用流式处理选项,如下所示: const sql = require('mssql') ... const request = new sql.Request() request.stream = true request.query('select * from verylargetable') request.on('row', row => {

我使用Node将200万行从SQL Server复制到另一个数据库,因此我当然使用流式处理选项,如下所示:

    const sql = require('mssql')
    ...
    const request = new sql.Request()
    request.stream = true
    request.query('select * from verylargetable')     
    request.on('row', row => {
        promise = write_to_other_database(row);
    })
我的问题是,我必须对插入到另一个数据库中的每一行执行异步操作,这需要时间

读取速度比写入速度快,所以在行事件不断发生,内存最终被挂起的承诺填满,最终导致节点崩溃。这是令人沮丧的-流媒体的全部目的就是避免这种情况,不是吗


如何解决此问题?

问题似乎是由于使用不允许您控制流流的行事件读取流造成的。使用管道方法应该可以做到这一点,但最终您将进入一个数据流并实现一个可写流——这可能很棘手

一个简单的解决方案是使用以下几行代码来完成:

const sql = require('mssql')
const {DataStream} = require("scramjet");
//...

const request = new sql.Request()
request.stream = true
request.query('select * from verylargetable')     
request.pipe(new DataStream({maxParallel: 1}))  
                        // pipe to a new DataStream with no parallel processing
    .batch(64)
                        // optionally batch the requests that someone mentioned
    .consume(async (row) => write_to_other_database(row));
                        // flow control will be done automatically

超燃冲压发动机将使用承诺来控制气流。您也可以尝试增加maxParallel方法,但请记住,在这种情况下,最后一行可能会同时开始推行。

问题似乎是由于使用不允许您控制流流的行事件读取流造成的。使用管道方法应该可以做到这一点,但最终您将进入一个数据流并实现一个可写流——这可能很棘手

一个简单的解决方案是使用以下几行代码来完成:

const sql = require('mssql')
const {DataStream} = require("scramjet");
//...

const request = new sql.Request()
request.stream = true
request.query('select * from verylargetable')     
request.pipe(new DataStream({maxParallel: 1}))  
                        // pipe to a new DataStream with no parallel processing
    .batch(64)
                        // optionally batch the requests that someone mentioned
    .consume(async (row) => write_to_other_database(row));
                        // flow control will be done automatically

超燃冲压发动机将使用承诺来控制气流。您也可以尝试增加maxParallel方法,但请记住,在这种情况下,最后一行可能会同时开始推送行。

我自己的答案:不是同时写入目标数据库,而是将每一行转换为insert语句,并将该语句推送到消息队列RabbitMQ,这是一个单独的进程。这是快速的,可以跟上阅读速度。另一个节点进程从队列中拉出的速度较慢,并写入目标数据库。因此,行的大日志是由消息队列本身处理的,它擅长于这类事情。

我自己的回答:我没有同时写入目标数据库,而是将每一行转换为insert语句,并将该语句推送到消息队列RabbitMQ,这是一个单独的进程。这是快速的,可以跟上阅读速度。另一个节点进程从队列中拉出的速度较慢,并写入目标数据库。因此,行的大日志是由消息队列本身处理的,它擅长于这类事情。

以流式传输数百万行而不会断断续续地崩溃。 断断续续地流成数百万行而不崩溃。
这是一次性手术吗?如果是这样的话,就使用SSMS。这只是我的观点,但似乎Node并不是用于此目的的合适工具-为什么不简单地使用SSIS?链接服务器、SSIS、OPENQUERY迁移200万行比使用Node有很多更好的选择。另一个数据库是Oracle,这不是一次性的事情-它必须是自动化的。所以你要查询200万行,然后迭代200万行中的每一行,分别插入每一行?然后您同时触发200万行插入事件,您希望服务器能够处理这一点吗?只是确定我了解这里的情况。这是一次性的行动吗?如果是这样的话,就使用SSMS。这只是我的观点,但似乎Node并不是用于此目的的合适工具-为什么不简单地使用SSIS?链接服务器、SSIS、OPENQUERY迁移200万行比使用Node有很多更好的选择。另一个数据库是Oracle,这不是一次性的事情-它必须是自动化的。所以你要查询200万行,然后迭代200万行中的每一行,分别插入每一行?然后您同时触发200万行插入事件,您希望服务器能够处理这一点吗?只是确保我了解这里的情况。