优化 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 查询如何使其更快的主要内容,如果未能解决你的问题,请参考以下文章

如何重写这个嵌套的 SQL 查询以使其更快? [关闭]

SQL查询性能调优--如何使查询更快

SQL数据库查询的优化

如何优化限制查询以更快地从大表中访问数据?

SQL查询慢,不知道如何优化

如何针对 db2 数据库优化 SQL/Python 选择查询?