我有一个包含tool_id,时间和消息的元组列表。我想从这个列表中选择消息匹配某个字符串的所有元素,以及时间在该工具的任何匹配消息的差异范围内的所有其他元素。如何让我的代码更高效?
这里是我当前如何这样做:
# record time for each message matching the specified message for each tool
messageTimes = {}
for row in cdata: # tool, time, message
if self.message in row[2]:
messageTimes[row[0], row[1]] = 1
# now pull out each message that is within the time diff for each matched message
# as well as the matched messages themselves
def determine(tup):
if self.message in tup[2]: return True # matched message
for (tool, date_time) in messageTimes:
if tool == tup[0]:
if abs(date_time-tup[1]) <= tdiff:
return True
return False
cdata[:] = [tup for tup in cdata if determine(tup)]
此代码的工作,但运行它花费的时间太长 - 例如当cdata有600,000个元素(这是我的应用程序的典型特征)需要2个小时才能运行。
该数据来自数据库。最初我只是使用SQL获取我想要的数据,但这也花了太长时间。我只是选择了我想要的消息,然后为每个人做了另一个查询,以获得每个时间差异内的数据。这导致了数以万计的查询。所以我改变了它一次拉出所有可能的匹配,然后用python处理它,认为这会更快。也许我错了。
任何人都可以给我一些关于加快速度的建议吗?
更新我的帖子,以显示我在SQL中的建议。
我在SQL中做的事很简单。第一个查询是这样的:
SELECT tool, date_time, message
FROM event_log
WHERE message LIKE '%foo%'
AND other selection criteria
这是足够快,但它可能会返回20或30万行。于是我在结果集中循环,并为每行跑这样的查询(其中DT和t是从一排DATE_TIME和工具从上面的选择):
SELECT date_time, message
FROM event_log
WHERE tool = t
AND ABS(TIMESTAMPDIFF(SECOND, date_time, dt)) <= timediff
这是需要大约一小时。
我也试过在一个嵌套查询中,内部查询从我的第一个查询中选择了行,而外部查询选择了时间差异行。这花了更长的时间。
因此,现在我选择了没有LIKE'%foo%'子句的消息,我找回600,000行并试图从python中取出所需的行。
我不写这作为一个答案,因为它是没有,但我的经验,你应该尝试做的就像你在SQL中一样。该语言和环境针对从数据库中分拣和挑选数据进行了优化。如果有什么可能,你可以发布你如何在SQL中做到这一点,我们可以尝试优化。 – Mathias
+1给Mathias。与查询后接子查询不同,您应该使用连接(或者,如果这不可能,SQL中的子查询)执行查询。如果这需要太长时间,那几乎肯定只是你错过了一个关键指标。 – abarnert
我已更新我的帖子以显示我在SQL中做了什么。没有任何索引可以帮助解决这个问题。 –