Скорость с запросом и массовой вставкой лучше-SQLITE3
У меня проблема с производительностью, наш клиент отправляет примерно 47 тыс. Строк на сервер.
это стол.
Сервер должен проверить, что ему нужно делать с каждой строкой.
вот фрагмент кода.
var Prodbegin = ProdDb.prepare('BEGIN');
var Prodcommit = ProdDb.prepare('COMMIT');
Prodbegin.run();
const Replacestmnt = ProdDb.prepare("REPLACE INTO Log (ID, TimeStamp, Error, SyncID, DateChanged, PageChanged, SearchID, Item, Username, Description, EpsNum) VALUES ($ID, $TimeStamp, $Error, $SyncID, $DateChanged, $PageChanged, $SearchID, $Item, $Username, $Description, $EpsNum)");
const Insertstmnt = ProdDb.prepare("INSERT INTO Log (TimeStamp, Error, SyncID, DateChanged, PageChanged, SearchID, Item, Username, Description, EpsNum) VALUES ($TimeStamp, $Error, $SyncID, $DateChanged, $PageChanged, $SearchID, $Item, $Username, $Description, $EpsNum)");
console.log(data_decrypt.DBname + " LOG START");
for (let i = 0; i < data_decrypt.DataBaseRows.length; i++) {
const Row = data_decrypt.DataBaseRows[i];
//Creating TimeStamp
var d = new Date(Date.now()),
seconds = '' + d.getSeconds(),
minutes = '' + d.getMinutes(),
hour = '' + d.getHours(),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2) month = '0' + month;
if (day.length < 2) day = '0' + day;
const TodaysDate = year + '-' + month + '-' + day + " " + hour + ":" + minutes + ":" + seconds;
////////////////////////////////////////////////////////////////////////////////////////////////
const syncIDSearch = ProdDb.prepare("SELECT SyncID FROM Log WHERE SyncID ='" + Row.SyncID + "'").get();
if (Row.TimeStamp == "U") {
Replacestmnt.run({
ID: Row.ID,
TimeStamp: TodaysDate,
Error: Row.Error,
SyncID: Row.SyncID,
DateChanged: Row.DateChanged,
PageChanged: Row.PageChanged,
SearchID: Row.SearchID,
Item: "1",
Username: Row.Username,
Description: Row.Description,
EpsNum: Row.EpsNum
});
} else {
if (syncIDSearch == 0) {
Insertstmnt.run({
TimeStamp: TodaysDate,
Error: Row.Error,
SyncID: Row.SyncID,
DateChanged: Row.DateChanged,
PageChanged: Row.PageChanged,
SearchID: Row.SearchID,
Item: "1",
Username: Row.Username,
Description: Row.Description,
EpsNum: Row.EpsNum
});
}
}
}
Prodcommit.run();
console.log(data_decrypt.DBname + " LOG END");
две вещи, которые должны произойти: перед обновлением необходимо убедиться, что SYNCID одинаков, чтобы он мог обновить
перед вставкой необходимо убедиться, что SYNCID НЕ является тем же, чтобы его можно было вставить.
Я обнаружил, что изменение forloop для кэширования длины ускорило весь процесс... но теперь меня ограничивает QUERY на базе данных.
Я не могу использовать массив, чтобы выделить все снаружи и отфильтровать массив, как если бы одновременно синхронизировалось более одного клиента, это может привести к дублированию.
Я посмотрел на оператор обновления с проблемой условия WHERE (если мы создаем проблему кодирования, мы можем потерять данные)(чего не может быть, мы бы предпочли дублирование, а не пропущенные строки)
пожалуйста, обратите внимание, что идентификатор неизвестен, так как идентификатор клиента может совпадать с идентификатором на сервере, но это новая строка, когда клиент получает данные обратно, он заменит их той же информацией на сервере.
Итак, все, что мы знаем, это то, что SYNCID уникален для каждой строки каждым клиентом
поэтому мы изменили код сейчас на это
if (Row.TimeStamp == "U") {
//const Replacestmnt = ProdDb.prepare("REPLACE INTO Log (ID, TimeStamp, Error, SyncID, DateChanged, PageChanged, SearchID, Item, Username, Description, EpsNum) VALUES ($ID, $TimeStamp, $Error, $SyncID, $DateChanged, $PageChanged, $SearchID, $Item, $Username, $Description, $EpsNum)");
const Replacestmnt = ProdDb.prepare("UPDATE Log (TimeStamp = $TimeStamp, Error = $Error, DateChanged = $DateChanged, PageChanged = $PageChanged, SearchID = $SearchID, Item = $Item, Username = $Username, Description = $Description, EpsNum = $EpsNum WHERE SyncID = $SyncID");
Replacestmnt.run({
ID: Row.ID,
TimeStamp: TodaysDate,
Error: Row.Error,
SyncID: Row.SyncID,
DateChanged: Row.DateChanged,
PageChanged: Row.PageChanged,
SearchID: Row.SearchID,
Item: "1",
Username: Row.Username,
Description: Row.Description,
EpsNum: Row.EpsNum
});
} else {
try {
const Insertstmnt = ProdDb.prepare("INSERT INTO Log (TimeStamp, Error, SyncID, DateChanged, PageChanged, SearchID, Item, Username, Description, EpsNum) VALUES ($TimeStamp, $Error, $SyncID, $DateChanged, $PageChanged, $SearchID, $Item, $Username, $Description, $EpsNum)");
Insertstmnt.run({
TimeStamp: TodaysDate,
Error: Row.Error,
SyncID: Row.SyncID,
DateChanged: Row.DateChanged,
PageChanged: Row.PageChanged,
SearchID: Row.SearchID,
Item: "1",
Username: Row.Username,
Description: Row.Description,
EpsNum: Row.EpsNum
});
} catch (e) {
console.log("LINE EXISTS");
}
}
мы устанавливаем SYNCID в столбец UNIQUE, поэтому вставка работает отлично, просто выдает ошибку, но теперь для обновления... если мы оставим это в UPDATE, это может привести к отсутствию, как для REPLACE. Я не знаю, если мы используем
WHERE(SYNC ID == "+ Row.SYNCID +")
Забыл добавить... Я разместил вопрос на Github, спрашивающий, есть ли способ массовой вставки с помощью JSON или массива и т. Д., Но я не могу найти ничего, что также могло бы помочь, тогда мне не нужно проходить через for петля либо.