我正在尝试将超过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(', '));
答案 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(/"/gi, "\"");
consulta+= "transaction.executeSql('"+ins+"'); ";
jsonIndex++;
}
consulta+="});";
eval(consulta);
答案 4 :(得分:1)
我遇到了完全相同的问题。我找到了一篇提供可能解决方案的博文。 这是链接:http://blog.heldes.com/html5/sqlite-class-for-html5-database/
祝你好运
答案 5 :(得分:0)
在任何情况下,一个小时可能太长,但即使你减少了很多,你仍然需要等待很长时间。为了保持对用户的响应能力,可能需要生成一个新的线程来处理与UI线程分开的进程。