Оптимизация заполнения локальной базы данных WebSQL

Я пытаюсь оптимизировать скорость заполнения моей локальной базы данных в разрабатываемом веб-приложении. В настоящее время он использует PHP для доступа к базе данных, а затем вставляет эти данные в локальную базу данных, используя Javascript.

Проблема в том, что все, кроме пары записей, замедляет его, и я почти уверен, что он выполняет отдельный SQL-запрос для КАЖДОЙ строки. Я читал о транзакциях (коммиты и откаты, а что нет), и это похоже на ответ, но я не совсем уверен, как реализовать это или даже где.

Вот пример одной из функций, которая загружает конкретную таблицу.

<code>function ploadcostcodes()
{
$IPAddress = '';
$User = '';
$Password = '';
$Database = '';
$Company  = '';
$No='';
$Name='';
ploadSQLConnection($IPAddress,$User,$Password,$Database,$Company);
</code>

// Это подключается к фактической базе данных, откуда поступает информация.

<code>$Login = 'XXXXXXX';
$conn=mssql_connect($IPAddress,$Login,$Password);
 if (!$conn )
{
      die( print_r('Unable to connect to server', true));
}
 mssql_select_db($Database, $conn);

 $indent="        ";

$sql="SELECT Cost_Code_No as No, Description as Name, Unit_of_Measure FROM v_md_allowed_user_cost_codes WHERE Company_No = " . $Company . " and User_No = '" . $User . "'";

 $rs=mssql_query($sql);
 if (!$rs)
 {
   exit("No Data Found");
 }

 while ($row = mssql_fetch_array($rs))
 {
     $No = addslashes($row['No']);
     $Name = addslashes($row['Name']);
     $Name = str_replace("'",'`',$Name);
     $Unit = addslashes($row['Unit_of_Measure']);

  //THIS IS WHERE I SEE THE PROBLEM

     echo $indent."exeSQL(\"INSERT INTO Cost_Codes (Cost_Code_No,Name,Unit_of_Measure) VALUES('".$No."','".$Name."','".$Unit."')\",\"Loading Cost Codes...\"); \r\n";
 }
 mssql_free_result($rs);
 mssql_close($conn);
 return 0;
}
</code>

Я не знаю, для чего нужна транзакция (или даже если это то, что нужно сделать). Существует MSSQL для доступа к данным, SQLite для их вставки и Javascript, который выполняет код PHP.

Ответы на вопрос(1)

Решение Вопроса

Я подготовил бы запрос с заполнителями, затем выполнил бы его для каждой строки с правильными аргументами. Примерно так (только часть JS, используяunderscore.js для помощников массива):

db.transaction(function(tx) {
    var q = 'INSERT INTO Cost_Codes (Cost_Code_No, Name, Unit_Of_Measure) VALUES (?, ?, ?)';
    _(rows).each(function(row) {
        tx.executeSql(q, [row.code, row.name, row.unit]);
    });
});

Изменить: запрос с заполнителями имеет два основных преимущества:

It makes it a lot easier for the DB engine to cache and reuse query plans (because you are running the same query a hundred times instead of a hundred different queries once). It makes escaping data and avoiding SQL injections a lot easier.
 03 мая 2012 г., 06:03
@Pedro: это частьunderscore.js, _(array).each работает так же, какforEachвыполняет данную функцию для каждого элемента вarray.
 08 сент. 2013 г., 15:12
@VikrantY: да. Вы можете передатьsuccess callback иerror callback для каждогоexecuteSql call - ошибка обратного вызова может откатить всю транзакцию. Вместо того, чтобы использоватьeach, вы можете создать цепочку вызовов - создать функцию, которая вырезает одну строку изrows и выполняет запрос для этой строки, обратный вызов успеха запроса вызывает ту же функцию (поэтому он повторяется доrows становится пустым), и его обратный вызов ошибки откатывает транзакцию вместо этого. (Обратите внимание, что ожидание выполнения каждой строки перед началом следующей теряет скорость параллелизма. Возможны и другие решения.)
 08 сент. 2013 г., 15:04
Что если одна из вставок потерпит неудачу, как тогда будут управляться транзакции. Так как каждый executeSQL является асинхронным, он может вставить другой SQL до сбоя. Есть ли способ обойти это?
 20 февр. 2015 г., 01:06
К вашему сведению - если вы хотите узнать разницу в скорости с 1 транзакцией против 1 транзакции на запрос ... Я только что протестировал оба метода с 500+ запросами. Я обнаружил, что это было приблизительно 3 секунды для одной транзакции, по сравнению с 15 секундами с 500+ отдельными транзакциями.
 02 мая 2012 г., 22:45
Я не понимаю использование подчеркивания в строке 3.

Ваш ответ на вопрос