Все колбэки которые ты передаёшь в метод query встают в очередь на выполнение, за это время цикл успевает отработать до конца и когда берем значение итератора в колбэке, получаем значение по ссылке, в которой уже нарастили итератор до максимального, выход:
1. Передавать итератор в колбэк для каждого запроса --> (err, rows, fields, i)
2. Использовать forEach
[0,1,2,3].forEach(function(item, index){
setTimeout(function(){
console.log(index)
}, 0)
})