我有一个过程,在某些时候我需要在INTEGER类型的表中添加一个新列,然后我用UPDATE填充这个新列。我在C中这样做。
我可以将代码倾斜到
CREATE table t (a integer, b integer)
populate t
CREATE INDEX t_ndx on t (a)
ALTER TABLE t add c integer
用于更新列的C伪代码' c'看起来像这样
sqlite3_stmt u;
sqlite3_prepare_v2(db, "update t set c=? where a=?, -1, &u, 0);
for(i=0;i<n;i++)
{ c=c_a[i];
a=a_a[i];
sqlite3_bind_int64(u, 1, c);
sqlite3_bind_int64(u, 1, a);
sqlite3_step(u);
}
此UPDATE的顺序与创建t时的顺序相同。
我想知道sqlite3引擎是否检测到&#39;顺序&#39;访问并加快&#34;其中a =?&#34; (即保留一种前一个光标的缓存?
我也想知道是否有隐藏的&#39;像绑定数组一样的特征(至少在处理INTEGER时),以避免构造这样的循环并避免所有这些绑定并避免字节码执行所有那些沿着
行插入的东西sqlite3_stmt u;
sqlite3_prepare_v2(db, "update t set c=? where a=?, -1, &u, 0);
sqlite3_bind_int64_array(u, 1, c_a, n);
sqlite3_bind_int64_array(u, 1, a_a, n);
sqlite3_step_array(u,n);
提前完成 干杯 披
答案 0 :(得分:2)
您的代码已经非常优秀了。按a
搜索行需要单个索引查找和单个表行查找;两者都很快,因为所需的页面很可能已被缓存。
您可以通过将此列设为INTEGER PRIMARY KEY来加快a
上的查询速度,但只有当a
实际上是主键时才有意义。
理论上,可以一次更新多行:
UPDATE t
SET c = CASE a
WHEN :a1 THEN :c1
WHEN :a2 THEN :c2
WHEN :a2 THEN :c3
END
WHERE a IN (:a1, :a2, :a3);
但对于许多a
值,这很可能是作为对表的扫描实现的,所以只有在所有值都适合查询时才有意义,这对于大表是不可能的