2016-03-23 11 views
0

Ich habe einen Prozess, wo ich irgendwann eine neue Spalte zu einer Tabelle vom Typ INTEGER hinzufügen musste, dann musste ich diese neue Spalte mit einem UPDATE füllen. Ich tue dies in C.sqlite optimales Update nach einer alter table add

Ich kann meinen Code

CREATE table t (a integer, b integer) 
populate t 
CREATE INDEX t_ndx on t (a) 
ALTER TABLE t add c integer 

Der C Pseudo-Code der Spalte 'c' so aussehen zu aktualisieren beuge mich

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); 
} 

Die Reihenfolge der A sind das gleiche für dieses UPDATE wie das, das beim Erstellen von t angegeben wurde.

Ich würde gerne wissen, ob die sqlite3-Engine den "sequenziellen" Zugriff erkennt und das "where a =?" (dh eine Art Caching des vorherigen Cursors beibehalten?

Ich würde auch gerne wissen, ob es "versteckte" Funktion wie bindende Arrays gibt (zumindest wenn es sich um INTEGER handelt), um eine solche Schleife zu konstruieren und alles zu vermeiden diese Bindungen und vermeiden den Bytecode zu tun alle, fügen etwas entlang der Linie von

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); 

Danke im Voraus Prost Phi

Antwort

2

Ihr Code bereits ziemlich viel optimal. die Suche nach der Reihe von a braucht ein einzelne Indexsuche und eine einzelne Tabellenzeilensuche ; Beide werden schnell sein, da die benötigten Seiten wahrscheinlich bereits zwischengespeichert sind.

Sie könnten die Suche auf a beschleunigen, indem Sie diese Spalte die INTEGER PRIMARY KEY machen, aber das macht nur Sinn, wenn a tatsächlich der Primärschlüssel ist.

Theoretisch wäre es möglich, mehrere Zeilen auf einmal zu aktualisieren:

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); 

Aber für viele a Werte, dann ist dies wahrscheinlich als Scan über den Tisch umgesetzt werden, so wäre es nur Sinn machen wenn Sie alle Werte in die Abfrage einfügen könnten, was für eine große Tabelle nicht möglich ist.

+0

Danke CL für Ihre Antwort, ich werde das CASE-Beispiel für eine andere Situation behalten, die ich bekommen habe. Ich habe einen INDEX auf 'a' erstellt, in der Hoffnung, dass es die WHERE a =? Beschleunigen wird, ich dachte, es würde den Scan erleichtern, aber der =? Reihenfolge werde ich genau die Zeilenreihenfolge in 't' liefern, könnte ich dann den Scan von Rowid erzwingen, wenn der Scan von Rowid ist schneller als der Scan von Index auf Col 'a'. Ich kenne die Interna von sqlite3 nicht. Nochmals Danke. Phi – Phi

Verwandte Themen