improve id upgrade speed by a factor of 5

This commit is contained in:
Damien Elmes 2011-03-09 20:05:18 +09:00
parent 9c247f45bd
commit 59754eacb2
2 changed files with 23 additions and 8 deletions

View file

@ -2,6 +2,7 @@
# Copyright: Damien Elmes <anki@ichi2.net> # Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html # License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
import os
try: try:
from pysqlite2 import dbapi2 as sqlite from pysqlite2 import dbapi2 as sqlite
except ImportError: except ImportError:
@ -18,7 +19,7 @@ class DB(object):
self._db = sqlite.connect( self._db = sqlite.connect(
path, timeout=0, isolation_level=level) path, timeout=0, isolation_level=level)
self._path = path self._path = path
self.echo = False self.echo = os.environ.get("DBECHO")
def execute(self, sql, *a, **ka): def execute(self, sql, *a, **ka):
if self.echo: if self.echo:

View file

@ -213,6 +213,22 @@ def _moveTable(db, table, insExtra=""):
db.execute("drop table "+table) db.execute("drop table "+table)
_addSchema(db, False) _addSchema(db, False)
def _insertWithIdChange(db, map, idx, table, numVals):
"Fetching and re-inserting is a lot faster than row by row updates."
data = []
for row in db.all("select * from %s" % table):
row = list(row)
try:
row[idx] = map[row[idx]]
data.append(row)
except:
# referenced non-existant object
pass
db.execute("delete from %s" % table)
db.executemany(
"insert into %s values (?%s)" % (table, ",?"*(numVals-1)),
data)
def _upgradeSchema(db): def _upgradeSchema(db):
"Alter tables prior to ORM initialization." "Alter tables prior to ORM initialization."
try: try:
@ -230,9 +246,8 @@ def _upgradeSchema(db):
# move into temp table # move into temp table
_moveTable(db, "cards", " order by created") _moveTable(db, "cards", " order by created")
# use the new order to rewrite card ids # use the new order to rewrite card ids
for (old, new) in db.all("select id, rowid from cards2"): map = dict(db.all("select id, rowid from cards2"))
db.execute( _insertWithIdChange(db, map, 0, "reviewHistory", 12)
"update reviewHistory set cardId = ? where cardId = ?", new, old)
# move back, preserving new ids # move back, preserving new ids
db.execute(""" db.execute("""
insert into cards select rowid, factId, cardModelId, 1, ordinal, insert into cards select rowid, factId, cardModelId, 1, ordinal,
@ -269,10 +284,9 @@ create table facts2
insert into facts2 select id, modelId, created, modified, spaceUntil insert into facts2 select id, modelId, created, modified, spaceUntil
from facts order by created""") from facts order by created""")
# use the new order to rewrite fact ids # use the new order to rewrite fact ids
for (old, new) in db.all("select id, rowid from facts2"): map = dict(db.all("select id, rowid from facts2"))
db.execute("update fields set factId = ? where factId = ?", _insertWithIdChange(db, map, 1, "fields", 5)
new, old) _insertWithIdChange(db, map, 1, "cards", 18)
db.execute("update cards set fid = ? where fid = ?", new, old)
# and put the facts into the new table # and put the facts into the new table
db.execute("drop table facts") db.execute("drop table facts")
_addSchema(db, False) _addSchema(db, False)