我有一个非常简单的小型数据库,其中2个是:
节点(Node_ID, Node_name, Node_Date
):Node_ID是主键
引文(Origin_Id, Target_Id
):PRIMARY KEY (Origin_Id, Target_Id)
每个都是节点中的FK
现在我编写一个查询,首先找到他们的Origin_Id具有特定日期的所有引用,然后我想知道这些记录的目标日期是什么。
我在python中使用sqlite,Node表有3000条记录,Citation有9000条记录, 我的查询在函数中是这样的:
def cited_years_list(self, date):
c=self.cur
try:
c.execute("""select n.Node_Date,count(*) from Node n INNER JOIN
(select c.Origin_Id AS Origin_Id, c.Target_Id AS Target_Id, n.Node_Date AS
Date from CITATION c INNER JOIN NODE n ON c.Origin_Id=n.Node_Id where
CAST(n.Node_Date as INT)={0}) VW ON VW.Target_Id=n.Node_Id
GROUP BY n.Node_Date;""".format(date))
cited_years=c.fetchall()
self.conn.commit()
print('Cited Years are : \n ',str(cited_years))
except Exception as e:
print('Cited Years retrival failed ',e)
return cited_years
然后我把这个功能称为特定的年份,但它是疯狂的flashwwwwwwww :((特定年份大约1分钟) 虽然我的查询工作正常,但速度很慢。你能给我一个建议,让它更快吗?我很感激有关优化此查询的任何想法:)
我还应该提一下,我有关于Origin_Id和Target_Id的索引,所以内连接应该非常快,但它不是!!!
答案 0 :(得分:1)
如果此脚本运行一段时间,您可以考虑将数据库加载到内存中。由于您似乎在python中编码,因此有一个名为connection.backup的连接函数可以将整个数据库备份到内存中。由于内存比磁盘快得多,这应该会提高速度。当然,这并没有做任何事情来优化语句本身,因为我没有足够的代码来评估你在使用代码做什么。
答案 1 :(得分:1)
而不是COUNT(*)使用MAX(n.Node_Date)
SQLite没有对像mysql这样的表的数量保持计数器,而是每次调用COUNT时都会扫描所有行,这意味着速度非常慢..但是你可以使用MAX()来解决这个问题。