簡體   English   中英

使用Node.js將超過1m條記錄從SQL Server流式傳輸到MongoDB

[英]Streaming over 1m records from SQL Server to MongoDB using Node.js

我正在嘗試將8,000,000行數據從Microsoft SQL Sever復制到MongoDB。 它非常適合100,000條記錄,但是當我嘗試提取1,000,000條記錄(或全部)時,出現以下錯誤:

嚴重錯誤:CALL_AND_RETRY_LAST分配失敗-內存不足

這是我當前使用的代碼(咖啡):

MsSqlClient   = require 'mssql'
MongoClient = require('mongodb').MongoClient

config = {}
config.mongodb = 'mongodb://localhost:27017/dbname'
config.mssql = 'mssql://user::pass@host/dbname'

Promise.all(
  [
    MongoClient.connect config.mongodb
    MsSqlClient.connect config.mssql
  ]
).then (a) ->
  mongo = a[0]
  sql = a[1]

  collection = mongo.collection "collection_name"

  request = new MsSqlClient.Request()
  request.stream = true

  request.on 'row', (row) ->
    collection.insert(row)

  request.on 'done', (affected) ->
    console.log "Completed"

  sql.on 'error', (err) ->
    console.log err

  console.log "Querying"
  request.query("SELECT * FROM big_table")

.catch (err) ->
  console.log "ERROR: ", err

似乎對MongoDB的寫入要比從SQL Server進行下載花費的時間更長,我認為這是造成瓶頸的原因。 有沒有一種方法可以減慢(暫停/恢復)來自SQL Server的流,這樣我就可以在不添加SQL數據中的索引列和按行號進行選擇的情況下在塊中進行讀寫操作?

正在運行:

  • Windows 7,SQL Server 2012(SP1),MongoDB 2.8.0
  • Node.js 4.2.4 / mssql 3.3.0 / mongodb 2.1.19

您可以分塊進行(例如50'000)。 這里是一種方法(僅在SQL方面)如何實現(不是很快,但應該可以工作):

首先獲取塊,這些數字必須在SQL之外循環:

    -- get blocks

    select count(*) / 50000 as NumberOfBlocksToLoop
    from YOUR.TABLE

獲取塊,其中ColumnU是允許您對表進行排序的列(或者,您可以直接使用ID,但是如果從表中刪除數據,則可能會出現間隙問題):

    -- get first n-block

    declare @BlockNumber int

    set @BlockNumber = 1

    select ColumnX
    from
    (
        select row_number() over (order by ColumnU asc) as RowNumber,
        TABLE.ColumnX
        from YOUR.TABLE
    ) Data
    where RowNumber between ((@BlockNumber - 1) * 50000) + 1 and @BlockNumber * 50000

嘗試為您的塊找到合適的大小(當然取決於您的系統),以避免再次遇到內存不足異常。 您應該捕獲該異常,然后根據您的努力,刪除已傳輸的數據或計算較小的塊大小(難度稍大),然后繼續其余的傳輸。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM