v2.2.0
-
electron v13 binaries
-
BCP allows fast insert speed from client to a designated table. This is achieved via allocating fixed positions in memory binding each column on that table and re-populating/sending each row to the server. It is in effect a memory copy from the client to the table.
a 16 column Employee table mixed with binary, varchar, date, int and decimal can insert over 50k rows in 3 seconds (vs 25 seconds using non bcp) over a network, smaller tables speeds can be over 100k a second.
a 7 column table as shown inserts 100k rows in 3.5 seconds over a network - and that includes selecting 100 back to verify insert.
√ bcp employee (1144ms)
√ bcp 7 column mixed table (3753ms)
√ bcp expect error null in non null column (441ms)
√ bcp expect error duplicate primary key (68ms)
√ bcp recovery from error. (73ms)
√ bcp hierarchyid binary (165ms)
√ bcp small binary (105ms)
√ bcp bit bit (1379ms)
√ bcp uniqueidentifier (98ms)
√ bcp smallint (97ms)
√ bcp tinyint (90ms)
√ bcp real with null (90ms)
√ bcp real (89ms)
√ bcp bigint with nulls (82ms)
√ bcp bigint (100ms)
√ bcp time (99ms)
√ bcp numeric (103ms)
√ bcp varchar(max) (10k chars) (1806ms)
√ bcp datetimeoffset datetimeoffset - mix with nulls (145ms)
√ bcp datetimeoffset datetimeoffset (239ms)
√ bcp binary binary - mix with nulls (197ms)
√ bcp binary binary (203ms)
√ bcp bit bit - mix with nulls (101ms)
√ bcp timestamp timestamp - mix with nulls (119ms)
√ bcp timestamp timestamp - no null (127ms)
√ bcp varchar varchar with nulls (172ms)
√ bcp varchar varchar (139ms)
√ bcp int, int column - with nulls (108ms)
√ bcp int, int column (125ms)
29 passing (12s)
test('bcp 7 column mixed table ', testDone => {
async function test () {
function getNumeric (i) {
const v = Math.sqrt(i + 1)
return Math.round(v * 1e6) / 1e6
}
const bcp = new BcpEntry({
tableName: 'test_table_7_bcp',
columns: [
{
name: 'id',
type: 'INT PRIMARY KEY'
},
{
name: 's1',
type: 'VARCHAR (255) NULL'
},
{
name: 's2',
type: 'VARCHAR (100) NULL'
},
{
name: 'i1',
type: 'int null'
},
{
name: 'i2',
type: 'int NULL'
},
{
name: 'n1',
type: 'numeric(18,6) NULL'
},
{
name: 'n2',
type: 'numeric(18,6) NULL'
}]
}, i => {
return {
id: i,
s1: i % 2 === 0 ? null : `column1${i}`,
s2: `testing${i + 1}2Data`,
i1: i * 5,
i2: i * 9,
n1: getNumeric(i),
n2: getNumeric(i)
}
}, (actual, expected) => {
assert.deepStrictEqual(actual.length, expected.length)
for (let i = 0; i < actual.length; ++i) {
const lhs = actual[i]
const rhs = expected[i]
assert.deepStrictEqual(lhs.id, rhs.id)
assert.deepStrictEqual(lhs.s1, rhs.s1)
assert.deepStrictEqual(lhs.s2, rhs.s2)
assert.deepStrictEqual(lhs.i1, rhs.i1)
assert.deepStrictEqual(lhs.i2, rhs.i2)
assert(Math.abs(lhs.n1 - rhs.n1) < 1e-5)
assert(Math.abs(lhs.n2 - rhs.n2) < 1e-5)
}
})
return await bcp.runner(100000)
}
test().then((e) => {
testDone(e)
})
})
// see bcp.js unit tests - bind to a table
async create () {
const promisedQuery = util.promisify(theConnection.query)
const tm = theConnection.tableMgr()
const promisedGetTable = util.promisify(tm.getTable)
await promisedQuery(this.dropTableSql)
await promisedQuery(this.createTableSql)
const table = await promisedGetTable(this.tableName)
return table
}
}
// set the flag to turn on bcp and send rows to server using fast memory copy.
theConnection.setUseUTC(false)
const table = await helper.create()
table.setUseBcp(true)
const promisedInsert = util.promisify(table.insertRows)
const promisedQuery = util.promisify(theConnection.query)
This protocol is not part of the ODBC specification and its use therefore depends on using correct ODBC driver. For linux users, this should work out the box as ODBC 17 is the only driver supported and this is one used for BCP. The feature has been tested on Ubuntu, MacOS, Debian and Alpine.
For windows users, older drivers can still be used on all non bcp functions just as before - however presently only ODBC 17 is supported for bcp. Hence you need to have installed ODBC data source "ODBC Driver 17 for SQL Server". No other driver will work and attempts to do so will probably crash the node instance.