我使用unixtime和userid遍历大量消息,我想在每个用户的24小时时间内找到消息数。我在codereview上发布了我的代码以获得一些帮助。从那里我优化了
cur.execute('SELECT unixtime FROM MessageType1 WHERE userID ='+str(userID[index])+' ORDER BY unixtime asc')
查询,因为我发现它损害了我的代码总运行时间7.2s的6.7s。我通过使用CREATE INDEX unixtime_times ON MessageType1 (unixtime asc)
在unixtime列上创建索引来优化它。现在该查询需要0.00117s而不是6.7s,但运行我的代码所需的总时间从7.2s增加到15.8s。除了索引之外,一切都没有变化。经过进一步检查,似乎messages = cur.fetchall()
在实施索引后需要15.3秒。有谁知道为什么?提前谢谢!
con = lite.connect(databasepath)
userID = []
messages = []
messageFrequency = []
with con:
cur = con.cursor()
#Get all UserID
cur.execute('SELECT DISTINCT userid FROM MessageType1')
userID = cur.fetchall()
userID = {index:x[0] for index,x in enumerate(userID)}
#For each UserID
for index in range(len(userID)):
messageFrequency.append(0)
#Get all MSG with UserID = UserID sorted by UNIXTIME
cur.execute('SELECT unixtime FROM MessageType1 WHERE userID ='+str(userID[index])+' ORDER BY unixtime asc')
messages = cur.fetchall()
messages = {index:x[0] for index,x in enumerate(messages)}
#Loop through every MSG
for messageIndex in range(len(messages)):
frequency = 0
message = messages[messageIndex]
for nextMessageIndex in range(messageIndex+1, len(messages)):
#Loop through every message that is within 24 hours
nextmessage = messages[nextMessageIndex]
if nextmessage < message+(24*60*60):
#Count the number of occurences
frequency += 1
else:
break
#Add best benchmark for every message to a list that should be plotted.
if messageFrequency[-1]<frequency:
messageFrequency[-1] = frequency
答案 0 :(得分:2)
此查询的最佳索引:
SELECT unixtime
FROM MessageType1
WHERE userID ='+str(userID[index])+'
ORDER BY unixtime asc
是MessageType1(UserId, unixtime)
。
仅使用unixtime
索引,数据库基本上有两个可能的执行计划:
我的猜测是,它会根据您的时间选择第二种方法。处理的“获取”组件结束了查询的执行,因此非常快。然后它必须读取整个表格以获得您想要的结果。
由于地点问题,此方法可能需要更长时间才能按顺序读取数据。没有索引,它将读取第一页和第一页上的所有记录。使用索引,每条记录都在随机页面上 - 没有位置。当表大于可用于页面缓存的内存时,这可能会特别成问题,并且最终会出现称为“颠簸”的情况。