【发布时间】:2021-04-01 15:00:57
【问题描述】:
在以下示例中,t 是一个递增序列,在 100 万行中大致从 0 到 5,000,000。
import sqlite3, random, time
t = 0
db = sqlite3.connect(':memory:')
db.execute("CREATE TABLE IF NOT EXISTS data(id INTEGER PRIMARY KEY, t INTEGER, label TEXT);")
for i in range(1000*1000):
t += random.randint(0, 10)
db.execute("INSERT INTO data(t, label) VALUES (?, ?)", (t, 'hello'))
使用索引选择一个范围(假设 t = 1,000,000 ... 2,000,000):
db.execute("CREATE INDEX t_index ON data(t);")
start = time.time()
print(list(db.execute(f"SELECT COUNT(id) FROM data WHERE t BETWEEN 1000000 AND 2000000")))
print("index: %.1f ms" % ((time.time()-start)*1000)) # index: 15.0 ms
比不使用索引快 4-5 倍:
db.execute("DROP INDEX IF EXISTS t_index;")
start = time.time()
print(list(db.execute(f"SELECT COUNT(id) FROM data WHERE t BETWEEN 1000000 AND 2000000")))
print("no index: %.1f ms" % ((time.time()-start)*1000)) # no index: 73.0 ms
但数据库大小至少比索引大 30%。
问题:总的来说,我了解索引是如何大幅加速查询的,但是在t 是整数+递增的这种情况下,为什么还需要索引来加速查询?
毕竟,我们只需要找到 t=1,000,000 的行(这在 O(log n) 中是可能的,因为序列在增加),找到 t=2,000,000 的行,然后我们就有了范围.
TL;DR:当一列是一个递增的整数序列时,有没有办法对一个范围进行快速查询, 不必增加 30% 的数据库大小索引?
例如通过在创建表时设置参数,通知Sqlite该列正在增加/已经排序?
【问题讨论】:
标签: python database sqlite indexing database-performance