优化 sql 查询如何使其更快
Posted
技术标签:
【中文标题】优化 sql 查询如何使其更快【英文标题】:How Optimize sql query make it faster 【发布时间】:2011-05-07 08:21:08 【问题描述】:我有一个非常简单的小型数据库,其中 2 个表是:
Node (Node_ID, Node_name, Node_Date
) : Node_ID 是主键Citation (Origin_Id, Target_Id
) : PRIMARY KEY (Origin_Id, Target_Id)
每个都是 Node 中的 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
然后我在某些特定年份调用此函数,但这太疯狂了 slowwwwwwwwww :((特定年份大约 1 分钟) 虽然我的查询工作正常,但速度很慢。你能给我一个建议,让它更快吗?我将不胜感激有关优化此查询的任何想法:)
我还应该提到我在 Origin_Id 和 Target_Id 上有索引,所以内部连接应该很快,但不是!!!
【问题讨论】:
你为什么要执行count(*)? 还包括表的完整架构 嗨,这个数据是关于法庭案件的,我想知道“对于特定的年份,他们引用以前的案例的时间有多长,如果他们引用了 1990 年的 2 个案例,我想知道要知道它们是 2"。换句话说,我使用 count(*) 是因为我想了解特定 Origion_ID 的 target_ID 日期的分布。清楚了吗? 【参考方案1】:如果此脚本运行一段时间,您可以考虑将数据库加载到内存中。由于您似乎在使用 python 进行编码,因此有一个名为 connection.backup 的连接函数可以将整个数据库备份到内存中。由于内存比磁盘快得多,这应该会提高速度。当然,这对优化语句本身没有任何作用,因为我没有足够的代码来评估你对代码所做的事情。
【讨论】:
非常感谢您的回答,我可能会这样做,但对我来说奇怪的是,对于特定日期,此查询大约需要 1 分钟,这太疯狂了。它只是一个连接和一个条件,应该很快!我也有关于 target_ID , Origin_ID 的索引,我真的不知道出了什么问题,它与 sqlite 有关吗?我将整个函数粘贴到我的问题中,你知道吗?【参考方案2】:使用 MAX(n.Node_Date) 代替 COUNT(*)
SQLite 不会像 mysql 那样对表的数量进行计数器,而是在每次调用 COUNT 时扫描所有行,这意味着非常慢。但是你可以使用 MAX() 来解决这个问题。
【讨论】:
以上是关于优化 sql 查询如何使其更快的主要内容,如果未能解决你的问题,请参考以下文章