I am recently learning node.js and trying to duplicate a small website from flask/python to Node.js. Due to memory constraint I ended up with using SQLite as my production database – although it says never to use SQLite for production XD.
One thing I noticed is that node-sqlite3 (the most active module from Node.js community for SQLite access) seems to a little bit sluggish compared to python, especially when doing pagination. Really? Everything in Node.js is async and shouldn’t it be more responsive? Baffled and curious, I did follow comparison: do multiple SELECT on a small database file (223 megabyes) and time it. Below is my code for each:
Node.js
var sqlite3 = require('sqlite3').verbose(); var util=require('util'); var dbfn = './db.sqlite'; var db = new sqlite3.Database(dbfn,sqlite3.OPEN_READONLY, function(err) { if(err) { console.log(err); } else { var perpage=10,max=500,table='data2012',kw='sa'; for(var offset=1;offset<max;offset+=perpage) { stmt = util.format('select * from %s where xxx like "%s%" limit %d offset %d',table, kw, perpage, offset); db.all(stmt); } } });
Python:
import sqlite3 DATABASE = './db.sqlite' db=None try: db = sqlite3.connect(DATABASE) except: sys.stderr.write(os.getcwd()) table='data2011' kw=('sa%',) perpage=10 max=500 for offset in xrange(1,max,perpage): stmt = 'select * from %s where xxx like ? limit %d offset %d'%(table, perpage, offset) rs = db.execute(stmt, kw) rs.fetchall() db.close()
Ignore the table/columns the point is that it has more than enough data to complete the loop. Each was run 3 times and here’s the average:
- Node-sqlite3: 2.945s
- Python 1.542s
Looks like Python module is a lot faster. To eliminate any possible uncertainty I increased the loop# to be 1000. Again I ran each for 3 times for an average:
- Node-sqlite3: 10.085s
- Python: 6.040s
Python is still faster, but the gap is shrinking. How about 3000 iterations?
- Node-sqlite3:1m5s
- Python: 56.154s
5000?
- Node-sqlite3: 2m23s
- Python: 2m28s
So the observation so far is that python-sqlite3 beats node-sqlite3 when offset is small (remember sqlite doesn’t really support offset; it reads off all the data and discard unneeded ones). When offset is getting large, both are getting equally slow. Maybe Node.js overall has a higher throughput its sqlite3 module is less satisfying, at least as of today.
BTW, one trick to optimize Sqlite access performance is to VACUUM the database. This made huge difference on my database file.