Query taking forever when using nodejs, but less than 1s with other apps.
See original GitHub issueThis specific query becomes really slow and then it gets back to normal as new data is inserted. It keeps oscillating. To make sure that I would be able to reproduce it constantly, I created a backup DB exactly when it got slow. I can give access to the database if required to run some tests. When I execute the following query using NodeJS it takes at least 1 minute, while using any other application it usually takes less than 1 second. I monitored the MySQL and I could see that the query stays in Sending data state for the whole time until it finishes. I can provide additional information and access to this database if required. I really need to fix this problem.
MySQL Server: 5.7.10-log NodeJS MySQL: 2.11.1 NodeJS: 6.2.2 IISNode: 0.2.21 IIS: 7.5+ Windows Server 2012 and Windows 7
NodeJS code:
var http = require('http'),
express = require('express'),
bodyParser = require('body-parser'),
cors = require('cors');
var app = express();
mysql = require('mysql');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(bodyParser.text());
app.use(cors());
app.post('/test', function(req,res){
var conn = mysql.createConnection({
host : '10.1.1.3',
user : 'test',
password : 'Test1234',
database : 'test',
debug: ['HandshakeInitializationPacket','ClientAuthenticationPacket','OkPacket', 'ComQueryPacket', 'ResultSetHeaderPacket']
});
conn.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + conn.threadId);
conn.query('SELECT s.* FROM can_status s INNER JOIN (account_company_symbol acs) ON s.canid = acs.canid WHERE company = '+conn.escape(req.body.company)+' AND idvehicle = '+conn.escape(req.body.idvehicle)+' AND time >= DATE_SUB((select max(time) from can_status WHERE idvehicle = '+conn.escape(req.body.idvehicle)+'), INTERVAL '+conn.escape(req.body.time)+' MINUTE) ORDER BY time DESC', function(error, results, fields){
if(error !== undefined && error !== null){
console.log(error);
conn.end()
res.send(error);
}
conn.end()
res.send(results);
});
});
});
app.listen(process.env.PORT, function () {
console.log('Example app listening on port'+process.env.PORT);
});
NodeJS Log:
Example app listening on port\\.\pipe\87c13d28-d1fe-4c3a-afa2-df979d56db0a
<-- HandshakeInitializationPacket
HandshakeInitializationPacket {
protocolVersion: 10,
serverVersion: '5.7.10-log',
threadId: 26514,
scrambleBuff1: <Buffer 6e 23 25 06 03 13 0d 34>,
filler1: <Buffer 00>,
serverCapabilities1: 63487,
serverLanguage: 33,
serverStatus: 2,
serverCapabilities2: 33279,
scrambleLength: 21,
filler2: <Buffer 00 00 00 00 00 00 00 00 00 00>,
scrambleBuff2: <Buffer 3e 4a 6b 37 79 2a 25 72 20 4f 27 59>,
filler3: <Buffer 00>,
pluginData: 'mysql_native_password',
protocol41: true }
--> ClientAuthenticationPacket
ClientAuthenticationPacket {
clientFlags: 455631,
maxPacketSize: 0,
charsetNumber: 33,
filler: undefined,
user: 'test',
scrambleBuff: <Buffer e2 56 b0 51 5f 27 ac 8a 45 55 50 37 bc b3 04 0e 98 25 72 c5>,
database: 'test',
protocol41: true }
<-- OkPacket
OkPacket {
fieldCount: 0,
affectedRows: 0,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 }
connected as id 26514
--> ComQueryPacket
ComQueryPacket {
command: 3,
sql: 'SELECT s.* FROM can_status s INNER JOIN (account_company_symbol acs) ON s.canid = acs.canid WHERE company = \'Efficient Drivetrains Inc.\' AND idvehicle = \'4\' AND time >= DATE_SUB((select max(time) from can_status WHERE idvehicle = \'4\'), INTERVAL \'5\' MINUTE) ORDER BY time DESC' }
<-- ResultSetHeaderPacket
ResultSetHeaderPacket { fieldCount: 5, extra: undefined }
Thank you very much!
Issue Analytics
- State:
- Created 7 years ago
- Comments:12 (7 by maintainers)
Two suggestions:
Number of records returned
Is it possible this has to do with number of records returned, i.e. workbench has a default limit of 1000. If you add
limit 1000
to your query does it perform better?indices are type sensitive
If you are using indices you need to make sure that any terms in the query are the same type as the field itself as defined in the table. For example if
idvehicle
is a defined as numeric variable in the table but you search as string (i.e. put the search term in quotes), oridvehicle
is a string in the DB but you search with a integer (i.e. unquoted number) then in both cases the index foridvehicle
will not be used and a full tablescan will be performed.Hi @caio-porto, I’m glad to hear you figured it out 😃!