【问题标题】:Efficient way to insert rows in database from the android shell?从android shell在数据库中插入行的有效方法?
【发布时间】:2012-12-13 06:26:05
【问题描述】:

我正在寻找一种在数据库中高效插入约 200 行的方法,专门使用 android shell。

我正在使用的脚本的相关部分是:

while read line
do
    uid=`echo $line " awk '{print($2)}'`
    pkg=`echo $line " awk '{print($1)}'`
    /system/xbin/sqlite3 /mnt/sdcard/apps.db "INSERT INTO app_list values($uid, '$pkg', 0, 0, 0, 0, 0, 0)
done < /data/system/packages.list

此脚本的目标是生成一个数据库,其中包含所有已安装应用程序的列表(UID/包名称)。其他列稍后使用。

对于约 200 个应用程序,此脚本需要几分钟:每个 sqlite 命令需要约 2 秒才能执行。这应该通过使用事务来大大改善,但我看不出有明确的方法来做到这一点。

任何帮助将不胜感激,

谢谢。

编辑:

回复帖子 #1:
已更改:
qry=$qry ($uid, '$pkg', 0, 0, 0, 0, 0, 0), 更改为 qry=$qry" ($uid, '$pkg', 0, 0, 0, 0, 0, 0),"
/system/xbin/sqlite3 /mnt/sdcard/apps.db $qry/system/xbin/sqlite3 /mnt/sdcard/apps.db "$qry;"
回显最后一条命令显示:
/system/xbin/sqlite3 /mnt/sdcard/apps.db INSERT INTO app_list VALUES (10028, 'com.google', 0, 0, 0, 0, 0, 0), (10048, 'com.google.something', 0, 0, 0, 0, 0, 0), ... (10062, 'com.google.somethingelse', 0, 0, 0, 0, 0, 0);
这似乎是正确的,但在执行时会输出以下错误:
SQL error: near ",": syntax error

【问题讨论】:

  • 您可以尝试连接所有以分号分隔的 INSERT 并一次性传递吗?
  • 您可以通过 awk 脚本运行您的输入文件以创建一批插入语句(如果是 tmp 文件),然后将该 tmpfile 重定向到 sqllite3(在顶部和底部添加任何所需的额外内容) .祝你好运。

标签: android sql database shell sqlite


【解决方案1】:

每行 2 秒的大部分时间可能都花在了每次命令运行并在之后退出时启动一个新的 sqlite 实例,因此只需一次添加所有行即可获得很多加速.

您可以insert multiple rows in a single SQL query,因此最好将一个巨大的字符串与所有插入值连接起来。 bash 脚本看起来像这样。

qry=""
while read line
do
    uid=`echo $line " awk '{print($2)}'`
    pkg=`echo $line " awk '{print($1)}'`
    qry="$qry INSERT INTO app_list VALUES ($uid, '$pkg', 0, 0, 0, 0, 0, 0);"

done < /data/system/packages.list

/system/xbin/sqlite3 /mnt/sdcard/apps.db "$qry;"

编辑:

澄清一下,此脚本使用“INSERT INTO TBL VALUES (row 1 vals), (row 2 vals), (row 3 vals);”语法,因为 SQLite 不支持它。

【讨论】:

  • 感谢您的回答。我稍微修改了一下并试了一下,但它给了我一个语法错误,即使一切看起来都是正确的。详情请查看编辑。
  • 好吧——经过一番研究,显然 Sqlite 不支持一个插入语句中的多个值的语法。我已经修改了示例脚本,只生成了一堆插入语句。不过,它仍然应该节省大量的执行时间,因为 sqlite 只需要打开一次。
  • 好的,现在可以正确执行了。执行时间几乎相同(公平地说,我认为它从〜3-4m下降到〜1.5m,但这只是从屏幕超时和我的记忆来看的印象)。但是,我现在可以轻松添加 BEGIN;开始并提交;到命令的末尾,这使事情变得更快(总共约 5 秒,实际的 sqlite 命令是即时的):/system/xbin/sqlite3 /mnt/sdcard/apps.db "BEGIN; $qry; COMMIT;"
  • 使用原子提交sqlite,速度类似于使用RAM数据库,但你应该考虑如果停止“原子提交”,就会丢失所有在“BEGIN;”之间执行的sql语句和“提交;”
猜你喜欢
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
相关资源
最近更新 更多