sqlite table:
CREATE TABLE IF NOT EXISTS INFO
(
uri TEXT PRIMARY KEY,
cap INTEGER,
/* some other columns */
uid TEXT
);
INFO
表有5K +行,可在低功耗设备上运行(与3年前的手机相当)。
我有这个任务:在INFO
表中插入带有一些值的新URI,但是,如果URI已经存在,那么我需要通过向其添加额外的文本来更新uid
文本字段 if < / em>在现有uid
字符串中找不到要追加的额外文本;所有其他字段应保持不变。
举个例子:INFO已经uri=
“http://example.com”与此uid
字符串:“| 123 || abc || xxx |”。
我需要添加uri
=“http://example.com”和uid
=“| abc |”。自“| abc |”是uri的现有字段中的子字符串,则不应更新任何内容。无论如何,不应更新剩余的字段
为了完成它,我有以下选择:
考虑到这是受约束的设备,哪种方式更可取?如果我省略了子字符串匹配的额外要求并且总是将uid附加到现有的uid字段,该怎么办?
答案 0 :(得分:1)
“如果在一个sql语句中可以使用sqlite”:
是的,有可能。在这个question中已经很好地讨论了“UPSERT”语句。
适用于您的扩展案例,您可以在一个声明中这样做:
insert or replace into info (uri, cap, uid)
values ( 'http://example.com',
coalesce((select cap from info where uri = 'http://example.com'),'new cap'),
(select case
when (select uid
from info
where uri = 'http://example.com') is null
then '|abc|'
when instr( (select uid
from info
where uri = 'http://example.com'),'|abc|') = 0
then (select uid
from info
where uri = 'http://example.com') || '|abc|'
else (select uid
from info
where uri = 'http://example.com')
end )
);
检查EXPLAIN QUERY PLAN给我们
selectid order from detail
---------- ---------- ---------- -------------------------
0 0 0 EXECUTE SCALAR SUBQUERY 0
0 0 0 SEARCH TABLE info USING INDEX sqlite_autoindex_INFO_1 (uri=?)
0 0 0 EXECUTE SCALAR SUBQUERY 1
1 0 0 EXECUTE SCALAR SUBQUERY 2
2 0 0 SEARCH TABLE info USING INDEX sqlite_autoindex_INFO_1 (uri=?)
1 0 0 EXECUTE SCALAR SUBQUERY 3
3 0 0 SEARCH TABLE info USING INDEX sqlite_autoindex_INFO_1 (uri=?)
1 0 0 EXECUTE SCALAR SUBQUERY 4
4 0 0 SEARCH TABLE info USING INDEX sqlite_autoindex_INFO_1 (uri=?)
1 0 0 EXECUTE SCALAR SUBQUERY 5
5 0 0 SEARCH TABLE info USING INDEX sqlite_autoindex_INFO_1 (uri=?)
据我所知,sqlite不会缓存标量子查询的结果(当查看EXPLAIN为上述语句生成的VM代码时,我找不到任何chaching的证据)。因此,由于sqlite是进程内数据库,因此使用两个单独的语句执行操作很可能比这更好。
您可能希望对此运行时进行基准测试 - 结果当然取决于您的主机语言和您使用的接口(C,JDBC,ODBC,...)。
修改强>
使用JDBC驱动程序和sqlite 3.7.2进行一点性能基准测试,在表信息中的5000行基本数据集上运行100,000次修改,50%更新,50%插入,确认了上述结论:
运行时间在几次运行中非常稳定。