【问题标题】:Optimizing WebSQL Local Database Population优化 WebSQL 本地数据库填充
【发布时间】:2012-04-19 08:53:13
【问题描述】:

我正在尝试优化本地数据库在正在开发的 Web 应用程序中的填充速度。目前,它使用 PHP 访问数据库,然后使用 Javascript 将该数据插入本地数据库。

问题是,除了几个条目之外的任何内容都会减慢它的速度,我很确定这是因为它为每一行执行单独的 SQL 查询。我一直在阅读事务(提交和回滚等等),这似乎是一个答案,但我不完全确定如何实现它,甚至不知道在哪里实现。

这是加载特定表的函数之一的示例。

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

// 这会连接到信息来源的实际数据库。

$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;
}

我不知道交易需要什么(或者即使那是需要做的)。有用于访问数据的 MSSQL、用于插入数据的 SQLite 和运行 PHP 代码的 Javascript。

【问题讨论】:

    标签: php javascript sqlite web-sql


    【解决方案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]);
        });
    });
    

    编辑:带占位符的查询有两个主要好处:

    1. 它使数据库引擎更容易缓存和重用查询计划(因为您运行相同的查询一百次,而不是一百次不同的查询一次)。
    2. 它使转义数据和避免 SQL 注入变得更加容易。

    【讨论】:

    • 第3行下划线的用法我不明白。
    • @Pedro:它是underscore.js 的一部分,_(array).each 与forEach 一样工作,为array 中的每个元素执行给定的函数。
    • 如果其中一个插入失败,那么如何管理事务。由于每个 executeSQL 都是异步的,它可能会在失败之前插入其他 SQL。有没有办法解决这个问题。
    • @VikrantY:是的。您可以将 成功回调 和 错误回调 传递给每个 executeSql 调用 - 错误回调可以回滚整个事务。您可以创建一个调用链,而不是使用each,而是创建一个函数,从rows 中删除一行并执行该行的查询,查询的成功回调调用相同的函数(因此它会重复到@987654330 @ 变为空)并且其错误回调将回滚事务。 (注意,在开始下一行之前等待每一行执行会失去并行速度。其他解决方案也是可能的。)
    • 仅供参考 - 如果您想知道 1 个事务与每个查询 1 个事务的速度差异......我刚刚测试了这两种方法,有 500 多个查询。我发现 1 笔交易大约需要 3 秒,而 500 多笔交易需要 15 秒。
    猜你喜欢
    • 1970-01-01
    • 2015-12-31
    • 2014-10-04
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多