2013-09-07 2 views
1

Я создаю приложение с угловыми и узловыми js. У меня очень большой запрос (insert query), который вставляет что-то вроде 30 000 строк, которые по какой-то причине занимают несколько минут (я полагаю, это нормально).node - mysql query, который занимает несколько минут, повторяющийся через несколько минут до завершения исходного запроса.

это мой запрос:

this.createCourts = function (req, res, next){ 
    console.log("entered creation courts"); 
     connection.query('CALL filldates("' + 
     req.body['startDate'] + '","' + 
     req.body['endDate'] + '","' + 
     req.body['numOfCourts'] + '","' + 
     req.body['duration'] + '","' + 
     req.body['sundayOpen'] + '","' + 
     req.body['mondayOpen'] + '","' + 
     req.body['tuesdayOpen'] + '","' + 
     req.body['wednesdayOpen'] + '","' + 
     req.body['thursdayOpen'] + '","' + 
     req.body['fridayOpen'] + '","' + 
     req.body['saturdayOpen'] + '","' + 
     req.body['sundayClose'] + '","' + 
     req.body['mondayClose'] + '","' + 
     req.body['tuesdayClose'] + '","' + 
     req.body['wednesdayClose'] + '","' + 
     req.body['thursdayClose'] + '","' + 
     req.body['fridayClose'] + '","' + 
     req.body['saturdayClose'] + 
     '");', function(err, result, fields){ 

     if (err){ 
      console.log("error is" + err); 
      return res.send(500, "fail");    
     } 
     else{ 
      console.log("finsihed"); 
      return res.send(200); 
     } 
     }); 
    }); 
}; 

мой пользовательский интерфейс будет нажать на кнопку, которая будет запускать услугу, как это:

CourtsService.createCourts.save({}, 
    {"startDate": dateService.Date_toYMD($scope.startDate), 
    "endDate": dateService.Date_toYMD($scope.endDate), 
    "numOfCourts": $scope.numOfCourts, 
    "duration": $scope.duration, 
    "sundayOpen": $scope.sundayOpen.hour, 
    "mondayOpen": $scope.mondayOpen.hour, 
    "tuesdayOpen": $scope.tuesdayOpen.hour, 
    "wednesdayOpen": $scope.wednesdayOpen.hour, 
    "thursdayOpen": $scope.thursdayOpen.hour, 
    "fridayOpen": $scope.fridayOpen.hour, 
    "saturdayOpen": $scope.saturdayOpen.hour, 
    "sundayClose": $scope.sundayClose.hour, 
    "mondayClose": $scope.mondayClose.hour, 
    "tuesdayClose": $scope.tuesdayClose.hour, 
    "wednesdayClose": $scope.wednesdayClose.hour, 
    "thursdayClose": $scope.thursdayClose.hour, 
    "fridayClose": $scope.fridayClose.hour, 
    "saturdayClose": $scope.saturdayClose.hour}, 
    function(data){ 
     $scope.showSearching = false; 
     $dialog.messageBox("success", btns).open(); 
    }, function(err){ 
     $scope.showSearching = false; 
     $dialog.messageBox("fail", err.data, btns).open(); 
    }); 

Я добавил эту строку на первой строке функции, которая будет на самом деле сделать запрос (его в коде здесь) console.log («введенные суды создания»);

Проблема заключается в том, что, поскольку запрос выполняется в течение нескольких минут (может быть 10 минут), кажется, что моя функция вызывается снова и снова, потому что я вижу на своей консоли строку «введенные суды создания», примерно каждые 1 минуту, и это, конечно, не то, что я хочу.

Я не знаю, что вызывает функцию createCourts снова и снова.

Возможно, это связано с тем, что пользовательский интерфейс переходит в режим ожидания и, таким образом, снова запускает услугу, если ответ не получен через 1 минуту (или что-то близкое к нему). и если это причина, почему я говорю службе просто ждать ответа?

ответ

1

Рассмотрите async api: на обработчике сервера сразу ответьте HTTP 200 и некоторым id, и есть еще одна конечная точка, чтобы проверить, завершена ли команда вставки с id.

Имейте в виду, что ваш код подвержен атаке для инъекций sql. Лучше подход:

var params = req.body; // you may want to filter names explicitly here 
connection.query('CALL filldates(?,?,?,?,...)', params, function(err, result, fields){ 
    if (err){ 
     console.log("error is" + err); 
     return res.send(500, "fail");    
    } 
    else{ 
     console.log("finsihed"); 
     return res.send(200); 
    } 
}); 

Это избежать всех опасных символов на клиенте перед отправкой запроса, или использовать подготовленные заявления с mysql2 отправить intdependent запроса параметров:

var params = req.body; // you may want to filter names explicitly here 
connection.execute('CALL filldates(?,?,?,?,...)', params, function(err, result, fields){ 
    if (err){ 
     console.log("error is" + err); 
     return res.send(500, "fail");    
    } 
    else{ 
     console.log("finsihed"); 
     return res.send(200); 
    } 
}); 

'несколько минут ИМХО слишком много , в моих тестах у меня скорость вставки около 10 тыс. строк в секунду. Попробуйте заменить инертные вызовы с генерацией большого текста запроса вставки и протестировать его с помощью клиента консоли. Если это все еще занимает несколько минут, тогда проблема не в земле узлов, вам нужно оптимизировать вашу базу данных.

+0

спасибо за ваш ответ. Я не понял, что означает эта строка: «и есть еще одна конечная точка, чтобы проверить, завершена ли команда вставки с id». и что такое «генерация большого текста запроса insesrt»? еще раз спасибо. – lobengula3rd

+0

второй вопрос - вместо того, чтобы делать большое количество «вставных» реквизитов, попробуйте создать одну большую строку sql со всеми вставками, сохраните ее в локальном файле и определите, сколько времени потребуется для выполнения 'cat myinserts.sql | mysql' –

+0

Я просто поручил эту функцию внутри транзакции, и теперь она занимает всего 5 секунд. Отличное спасибо :) – lobengula3rd

Смежные вопросы