【问题标题】:Nested SELECT queries sometimes stall嵌套的 SELECT 查询有时会停止
【发布时间】:2011-04-27 06:46:56
【问题描述】:

我一直在 python 应用程序中使用 sqlite3,在测试它时,我的查询有时会导致程序冻结。一个粗略的(凭记忆)示例:

SELECT id,name FROM main_table WHERE name IN 
(SELECT name FROM another_table WHERE another_table.attribute IN 
('foo', 'bar', 'baz'))

通常,当我第一次尝试这样的事情时,程序只是冻结了。现在,如果我先尝试子查询,然后再尝试整个嵌套的混乱,它几乎可以立即运行。

我猜它正在缓存第一个更简单查询的结果以供以后使用,这会使下一次的处理速度更快,但即便如此,我还是想知道如何首先避免这种停滞。

【问题讨论】:

    标签: python sql sqlite


    【解决方案1】:

    你没有提到任何关于索引的事情......两个表中的name 至少应该被索引。

    这是一个使用 JOIN 的等价物:

    SELECT DISTINCT
           x.id,
           x.name 
      FROM main_table x
      JOIN ANOTHER_TABLE y ON y.name = x.name
                          AND y.attribute IN ('foo', 'bar', 'baz')
    

    但请注意,如果 ANOTHER_TABLE 中有多个记录与 MAIN_TABLE 记录相关联 - JOIN 将产生重复项。因此需要 DISTINCT(或 GROUP BY,如果这是您的偏好)。

    EXISTS 可能是比 IN 更好的选择:

    SELECT x.id,
           x.name 
      FROM main_table x
     WHERE EXISTS(SELECT NULL
                    FROM ANOTHER_TABLE y 
                   WHERE y.name = x.name
                     AND y.attribute IN ('foo', 'bar', 'baz'))
    

    【讨论】:

    • 我对 SQL 很陌生,从来没有做过 JOIN,所以它会回到书本上。此外,似乎很多 SQL 性能问题都可以用“创建索引”来回答。虽然我可以看到这样做的语法,但我并不完全理解索引的作用。你能为我推荐一个解释吗?我不想在不了解它的情况下崇拜它并使用它。
    【解决方案2】:

    select ... where ... in ... 查询通常表现不佳。它们通常被优化器视为可能非常大的一系列(name=val1 or name=val2 or ... or name=valn)

    尝试对子查询使用内连接:

    选择 ID ,姓名 从 主表 INNER JOIN another_table on main_table.name=another_table.name 和另一个_table.attribute( 'foo','bar','baz' )

    【讨论】:

      猜你喜欢
      • 2019-08-08
      • 1970-01-01
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多