Javascript数据库批量插入

时间:2010-02-09 04:45:59

标签: iphone sql html5 webkit google-chrome

我正在尝试将超过70,000行插入到javascript数据库中(使用Chrome 5.0.317.2)。插件需要很长时间。实际页面在几秒钟内加载,我可以看到进度,因为插入每行时百分比增长非常缓慢。完成插入所有记录大约需要一个小时。有没有办法优化插入,或以某种方式从预加载的SQLite数据库开始?

<script src="jquery.1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
// Truncated to 1 row for example. There are really 76547 rows.
var zipcodes = var zipcodes = [{"city_name":"AMHERST","city_alias":"AMHERST","zipcode":"01002"}];
var db;
function openMyDatabase() {
    var shortName = 'mydb';
    var version = '1.0';
    var displayName = 'mydb';
    var maxSize = 65536;
    db = openDatabase(shortName, version, displayName, maxSize);
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'CREATE TABLE IF NOT EXISTS zipcode ' +
                '  (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
                '   city_name TEXT NOT NULL, ' +
                '   city_alias TEXT NOT NULL, ' +
                '   zipcode TEXT NOT NULL)'
            );
        }
    );
    $.each(zipcodes, function(i, zipcode) {
        insertZipcode(zipcode.city_name, zipcode.city_alias, zipcode.zipcode, i);
    });
}

function errorHandler(transaction, error) {
    alert('Oops. Error was '+error.message+' (Code '+error.code+')');
    return true;
}

function insertZipcode(cityName, cityAlias, zipcode, i) {
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'INSERT INTO zipcode (city_name, city_alias, zipcode) VALUES (?, ?, ?);',
                [cityName, cityAlias, zipcode],
                function(){
                    $('#counter').html((100 * i / zipcodes.length) + '%');
                },
                errorHandler
            );
        }
    );
    return false;
}

$(function() {
    openMyDatabase();
});
</script>

解决方案:在PHP方面,我创建了一个关联数组,并使用邮政编码作为键和一组城市作为值,我通过json_encode运行它并将其传递给javascript。在javascript方面,我可以使用以下代码快速获取特定邮政编码的城市列表:

var zipcodes = {"55437":["MINNEAPOLIS","BLOOMINGTON"]}; //truncated
alert('Cities in 55437: ' + zipcodes['55437'].join(', '));

6 个答案:

答案 0 :(得分:3)

我可以看到的一个问题是你试图一次插入一行,这会导致很多连接等开销......

如果你可以一次插入多行(一次可能是20或50)会更快。您可以使用一些有效的过程或INSERT INTO或其他东西插入多行。

答案 1 :(得分:3)

如果你不能将它移动到服务器端(Javascript实际上不是像这样的工作的工具),当然,像Suraj建议的那样捆绑多个插入。 90%的工作是开始连接,启动事务,结束事务,关闭连接。 10%是实际的数据库操作。

transaction.executeSql('
            INSERT INTO zipcode (city_name, city_alias, zipcode) VALUES (?, ?, ?);
            INSERT INTO zipcode (city_name, city_alias, zipcode) VALUES (?, ?, ?);
            INSERT INTO zipcode (city_name, city_alias, zipcode) VALUES (?, ?, ?);
            ... //20-50 lines like this, maybe generated by a loop.
            ',[
            cityName1, cityAlias1, zipcode1,
            cityName2, cityAlias2, zipcode2,
            cityName2, cityAlias3, zipcode3,
            ... // a matching table, generated by a loop as well.
            ],
            ...

答案 2 :(得分:1)

为什么不在网页加载时使用预加载的XML而不是创建所有字段?这样,您将减少加载时间,并且可以通过某种类型的索引(可能是哈希表索引或二进制搜索)来减少搜索时间。

这会降低灵活性,意味着您必须更改XML并在工具的帮助下编译它 - 我不知道是否存在类似的东西;但是可以提供更好的性能,特别是如果您使用的是iPhone等有限的设备。

答案 3 :(得分:1)

我为克服这个问题所做的是首先创建一个包含一个trasanction及其所有执行的字符串,然后使用javascript eval方法运行它

jsonResponse = Ext.util.JSON.decode(result.responseText);
        jsonIndex = 0;
        var consulta = "DB.transaction(function (transaction){";
        while(jsonResponse[jsonIndex] != null){
            var ins = jsonResponse[jsonIndex].instruccion;
            ins = ins.replace(/&quot;/gi, "\"");
            consulta+= "transaction.executeSql('"+ins+"'); ";                
            jsonIndex++;
        }
        consulta+="});";
        eval(consulta);

答案 4 :(得分:1)

我遇到了完全相同的问题。我找到了一篇提供可能解决方案的博文。 这是链接:http://blog.heldes.com/html5/sqlite-class-for-html5-database/

祝你好运

答案 5 :(得分:0)

在任何情况下,一个小时可能太长,但即使你减少了很多,你仍然需要等待很长时间。为了保持对用户的响应能力,可能需要生成一个新的线程来处理与UI线程分开的进程。