Skip to content

bad performance for hugh insert of escaped values #937

@ronny332

Description

@ronny332

Hello,

my normal usage of node-mysql (great lib, don't understand me wrong!) is to combine it with squel.js what works like a charm.

Today I had to migrate some old PHP code to node where a lot of sql inserts have to be done.

Every insert object contains 5 properties, at least I have to insert 50.000 to 100.000 rows at a time (of cause it is possible to split it to smaller pieces, but as it worked on the same way in PHP I'm searching for a reason for all of this).

As example I can provide some fake queries (created by squel and send to node-mysql):

var var inserts = [];
// up to 100.000 of this objects will be at the insert array
for (var i=0; i < 100000; ++i) {
  inserts.push({a:1, b:'abc', c:33, d:'78as', e:'foo'};
}
var sql = Squel.insert().into('tableName').setFieldsRows(inserts).toParam();

// squel.js creates a normal query like "INSERT INTO tableNAME (a,b,c,d,e) VALUES (?,?,?,?,?), (?,?,?,?,?), ... for sql.text.
// sql.values is an array with the insert objects [1,'abc',22,'78as','foo',..]
mysqlCon(sql.text, sql.values, function(err, result) {
  console.log('is not reached after minutes'):
});

From node-tick-processor I picked the following (reduced) output:

   ticks parent  name
   9062   58.4%  /opt/local/bin/node
   7322   80.8%    LazyCompile: *<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
   7322  100.0%      LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
   7322  100.0%        LazyCompile: *replace native string.js:221
   7322  100.0%          LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67
   7322  100.0%            LazyCompile: ~Connection.format /xxx/src/node_modules/mysql/lib/Connection.js:243
    370    4.1%    LazyCompile: ~<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
    370  100.0%      LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
    370  100.0%        LazyCompile: *replace native string.js:221
    370  100.0%          LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67
    370  100.0%            LazyCompile: ~Connection.format /xxx/src/node_modules/mysql/lib/Connection.js:243
    360    4.0%    LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
    334   92.8%      LazyCompile: *<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
    334  100.0%        LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
    334  100.0%          LazyCompile: *replace native string.js:221
    334  100.0%            LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67
     17    4.7%      LazyCompile: *replace native string.js:221
     15   88.2%        LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67
     15  100.0%          LazyCompile: ~Connection.format /xxx/src/node_modules/mysql/lib/Connection.js:243
     15  100.0%            LazyCompile: ~Connection.query /xxx/src/node_modules/mysql/lib/Connection.js:173
      2   11.8%        LazyCompile: *SqlString.escape /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:16
      2  100.0%          LazyCompile: *<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
      2  100.0%            LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
      9    2.5%      LazyCompile: ~<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
      9  100.0%        LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
      9  100.0%          LazyCompile: *replace native string.js:221
      9  100.0%            LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67

   5468   35.2%  /usr/lib/system/libsystem_kernel.dylib

    581    3.7%  /usr/lib/system/libsystem_platform.dylib
    495   85.2%    LazyCompile: *<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
    495  100.0%      LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
    495  100.0%        LazyCompile: *replace native string.js:221
    495  100.0%          LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67
    495  100.0%            LazyCompile: ~Connection.format /xxx/src/node_modules/mysql/lib/Connection.js:243
     31    5.3%    LazyCompile: ~<anonymous> /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:70
     31  100.0%      LazyCompile: *StringReplaceGlobalRegExpWithFunction native string.js:374
     31  100.0%        LazyCompile: *replace native string.js:221
     31  100.0%          LazyCompile: ~SqlString.format /xxx/src/node_modules/mysql/lib/protocol/SqlString.js:67
     31  100.0%            LazyCompile: ~Connection.format /xxx/src/node_modules/mysql/lib/Connection.js:243

Strange for me to see is a performance loss at about 10.000 entries. Lower values are calculated instantly, higher values are resulting in 100% cpu for minutes (I haven't waited for the completion).

Squel itself has to function to render the query as string (.toString()). There is no performance problem with the high amount of objects.

My workstation is an apple iMac i7 (model late 2013), the real testing environment is a huge dual xeon server with debian 7.0 on it. CPU power should not be the real reason for all of this ;-).

Is there anything I have to have to change at my code or is it just a limitation of node-mysql?

Thanks for any help or hint you can provide!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions