在SQLite上添加ORDER BY需要大量时间

在SQLite上添加ORDER BY需要大量时间,sql,sqlite,sql-order-by,common-table-expression,Sql,Sqlite,Sql Order By,Common Table Expression,我编写了以下查询: WITH m2 AS ( SELECT m.id, m.original_title, m.votes, l.name as lang FROM movies m JOIN movie_languages ml ON m.id = ml.movie_id JOIN languages l ON l.id = ml.language_id ) SELECT m.original_title FROM movies m WHERE NOT EX

我编写了以下查询:

WITH m2 AS (
    SELECT m.id, m.original_title, m.votes, l.name as lang
    FROM movies m
    JOIN movie_languages ml ON m.id = ml.movie_id 
    JOIN languages l ON l.id = ml.language_id
)
SELECT m.original_title 
FROM movies m
WHERE NOT EXISTS (
    SELECT 1
    FROM m2
    WHERE m.id = m2.id AND m2.lang <> 'English'
)
这不是数据的大小,因为整个表返回的结果是notime

我做错了什么?
为什么按订购会增加这么多时间?(查询
SELECT*FROM movies ORDER BY voces DESC
立即返回)。

CTE中的
ORDER BY
不相关。但我建议为此目的进行汇总:

SELECT m.original_title
FROM movies m JOIN
     movie_languages ml
     ON m.id = ml.movie_id JOIN
     languages l
     ON l.id = ml.language_id
GROUP BY m.original_title, m.id
HAVING SUM(lang = 'English') = 0;

您可以使用
notexists
,而不使用联接和聚合(假设表
movie\u languages
中的每部电影至少有一行):


有关更多信息,请参阅此链接:

简言之,当包含ORDERBY子句时,数据库将按正确的顺序构建行列表,然后按该顺序返回数据


创建上述列表需要大量额外的处理,转化为更长的执行时间。

为了检查查询,您可以在SQLite提示符下输入
.time on
打开计时器。更重要的是,利用EXPLAIN函数查看查询的详细信息

正如上面已经指出的,最初编写的查询似乎比需要的要复杂得多。一般来说,“movie_languages”和“languages”表的必要性似乎并不明显,尤其是在这个特定的查询中。这需要你做更多的解释,但我相信至少有一个可以删除,从而加快你的查询

SQLite中的ORDERBY子句的处理如下所述

SQLite尽可能尝试使用索引来满足查询的ORDER BY子句。当面临使用索引来满足WHERE子句约束或满足ORDER BY子句的选择时,SQLite会进行上述相同的成本分析,并选择它认为会产生最快答案的索引

SQLite还将尝试使用索引来帮助满足GROUPBY子句和DISTINCT关键字。如果联接的嵌套循环的排列方式可以使与GROUP BY或DISTINCT等价的行是连续的,则GROUP BY或DISTINCT逻辑可以通过将当前行与前一行进行比较来确定当前行是否为同一组的一部分,或者当前行是否为DISTINCT。这比将每一行与之前的所有行进行比较要快得多

由于没有关于投票的索引或类型,并且可能遵循上述逻辑,因此选择“它认为将产生最快答案的索引”。由于查询过于复杂,并且没有关于投票的索引,到那个时,投票被用作顺序,所以它需要找出比需要更多的东西。由于使用ORDERBY执行简单查询,因此查询的复杂性会导致SQLite的计算量大大超过需要

此外,列的类型(最可能是整数)在排序(和联接)时非常重要。尝试对字符类型进行排序不仅会得到错误的结果,在这种情况下,如果投票结果超过一位数,那么使用的类型将是错误的(我不认为您只是提到它)

因此,简化查询,确保主键设置正确,并对其进行测试。如果仍然没有及时返回,请尝试使用投票索引。这将使您更好地了解正在发生的事情以及不同的更改如何影响您的查询


但是在整个表中使用
按顺序排序所需的时间更少$:这是因为您没有“将两个查询合并到一个表中,然后按任何顺序排序”。您好,您能接受我的回答吗,谢谢。
SELECT m.original_title
FROM movies m JOIN
     movie_languages ml
     ON m.id = ml.movie_id JOIN
     languages l
     ON l.id = ml.language_id
GROUP BY m.original_title, m.id
HAVING SUM(lang = 'English') = 0;
SELECT m.*
FROM movies m
WHERE NOT EXISTS (
  SELECT 1 FROM movie_languages ml
  WHERE m.id = ml.movie_id
    AND ml.language_id <> (SELECT l.id FROM languages l WHERE l.lang = 'English')
)
ORDER BY m.votes DESC
SELECT m.*
FROM movies m 
INNER JOIN movie_languages ml ON m.id = ml.movie_id 
LEFT JOIN languages l ON l.id = ml.language_id AND l.lang <> 'English'
WHERE l.id IS NULL
ORDER BY m.votes DESC