Thursday, February 09, 2006

sqlite3 bugs?

使用:sqlite 3.2.7
schema:
CREATE TABLE msginfo(msgnum INTEGER PRIMARY KEY,msgtype INTEGER NOT NULL DEFAULT 0,msgts INTEGER NOT NULL,msgbtime INTEGER NOT NULL,msgtime INTEGER DEFAULT NULL,linenum INTEGER NOT NULL,msgtsbegin INTEGER NOT NULL DEFAULT 0,callid VARCHAR(255) DEFAULT '',dialstr VARCHAR(255) DEFAULT '',ownerid INTEGER NOT NULL,msgmemo TEXT DEFAULT NULL,user_type INTEGER,archived INTEGER DEFAULT NULL,source INTEGER DEFAULT NULL,orgidx INTEGER DEFAULT NULL,UNIQUE (msgts,linenum,ownerid));
CREATE INDEX Idx_comp on msginfo (ownerid,msgts);
CREATE INDEX Idx_msgts on msginfo (msgts);
CREATE INDEX idx_msgbtime ON msginfo(msgbtime);
CREATE INDEX idx_msgfile ON msginfo (msgts,linenum);
CREATE INDEX idx_msgtime ON msginfo(msgtime);
CREATE INDEX idx_msgtsbegin ON msginfo(msgtsbegin);
CREATE INDEX idx_ownerid ON msginfo (ownerid);

import pysqlite2.dbapi2 as sqlite
con = sqlite.connect('test.db')
cur = con.cursor()
pagelen = 50
cond = 'ownerid=20 AND msgtype=0'
cur.execute('SELECT COUNT(*) FROM msginfo WHERE %s' % cond)
total = cur.fetchone()[0]
pages = (total + pagelen - 1) //pagelen
print 'Total:%d'% total
for i in range(pages):
offset = i * pagelen
cur.execute('select * from msginfo where %s order by msgts desc limit 50 offset %d'% (cond, offset))
a = cur.fetchall()
begin = i*pagelen
sizeofa = len(a)
print 'offset = %d and data =%d (%d~%d)'% (offset,sizeofa, begin, begin + sizeofa)

---------------------------------------------------------------------------------
Total: 1978
offset = 0 and data =50 (0~50)
offset = 50 and data =50 (50~100)
offset = 100 and data =50 (100~150)
offset = 150 and data =50 (150~200)
offset = 200 and data =50 (200~250)
offset = 250 and data =50 (250~300)
offset = 300 and data =50 (300~350)
offset = 350 and data =50 (350~400)
offset = 400 and data =50 (400~450)
offset = 450 and data =50 (450~500)
.....
.....
offset = 1750 and data =50 (1750~1800)
offset = 1800 and data =50 (1800~1850)
offset = 1850 and data =50 (1850~1900)
offset = 1900 and data =50 (1900~1950)
offset = 1950 and data =31 (1950~1981)
------------------------------------------
紅色部分應該是28,因為1978 % 50 = 28

檢查SQL語法以及使用的Index:
bash-2.03# idxchk backupMsgInfo.db
SELECT COUNT(*) FROM msginfo WHERE ownerid = 20 AND msgtype = 0
table index(es) column(s)
------- ----------- ------------------------------
msginfo
msginfo idx_ownerid (ownerid)

bash-2.03# idxchk backupMsgInfo.db
SELECT * FROM msginfo WHERE ownerid = 20 AND msgtype = 0 ORDER BY msgts DESC LIMIT 50 OFFSET 1950
table index(es) column(s)
------- ---------- ------------------------------
msginfo
msginfo Idx_comp (ownerid,msgts)

使用的Index不同。現在強制取消使用Index:
sqlite3 backupMsgInfo.db
>SELECT * FROM msginfo WHERE +ownerid = 20 AND +msgtype = 0 ORDER BY msgts DESC LIMIT 50 OFFSET 1950;
219|0|948670669|73655|73749|2|948670615||1|20|||5||27
211|0|948670558|73505|73558|2|948670505||1|20|||5||26
203|0|948670447|73314|73407|2|948670394||1|20|||5||25
...
...
共28筆

結局:
資料庫Index不同步。
(到底是什麼鬼原因讓資料庫的Index不同步....)
解決方法:使用VACCUM

No comments: