Sql 如何从具有UNION ALL的查询中获得优化的分页列表?

Sql 如何从具有UNION ALL的查询中获得优化的分页列表?,sql,optimization,query-optimization,union-all,Sql,Optimization,Query Optimization,Union All,我有一个由来自两个表的联合组成的查询。必须对结果进行排序和分页(如web应用程序的典型列表) 原始查询(简化)为: 问题是这两个表的行数都超过了100万行,而且查询速度非常慢 如何从UNION ALL获得优化的分页列表 Postdata: 我使用了Stack Overflow的搜索,我发现了一些类似的问题,但是答案不正确或者问题不完全相同。两个例子: 我很惊讶在堆栈溢出中没有人能回答这个问题。也许不可能更有效地执行此查询?这个问题的解决方案是什么?我认为您可以在第二个链接中使用类似的解决方案

我有一个由来自两个表的联合组成的查询。必须对结果进行排序和分页(如web应用程序的典型列表)

原始查询(简化)为:

问题是这两个表的行数都超过了100万行,而且查询速度非常慢

如何从UNION ALL获得优化的分页列表

Postdata:

我使用了Stack Overflow的搜索,我发现了一些类似的问题,但是答案不正确或者问题不完全相同。两个例子:


我很惊讶在堆栈溢出中没有人能回答这个问题。也许不可能更有效地执行此查询?这个问题的解决方案是什么?

我认为您可以在第二个链接中使用类似的解决方案,至少可以帮助提高性能,但我怀疑您能否在以后的页面中获得出色的性能。例如:

(   SELECT name, id
    FROM _test1 -- conditions WHERE
    ORDER BY name DESC LIMIT 0, 30
)
UNION ALL
(   SELECT name, id
    FROM _test2 -- conditions WHERE
   ORDER BY name DESC LIMIT 0, 30
)
ORDER BY name DESC
LIMIT 10, 20
您基本上将每个子查询限制为给定页面上可能存在的行的子集。这样,您只需要从每个表中检索并合并20行,然后再确定返回哪10行。否则,服务器可能会从每个表中获取所有行,排序并合并它们,然后开始尝试查找正确的行

不过,我并不经常使用MySQL,所以我不能保证该引擎会按照我认为应该的方式运行:)


在任何情况下,一旦进入后面的页面,您仍然会合并越来越大的数据集。然而,我强烈认为UI不应该允许用户检索允许他们进入(例如)第5000页的一组记录。对于人类大脑来说,这些数据太多,无法一次找到所有有用的数据,因此需要进一步过滤。也许让他们看到前100页(或其他数字),但否则他们必须更好地限制结果。不过,这只是我的看法。

我认为您可以在第二个链接中使用类似的解决方案,至少有助于提高性能,但我怀疑您能否在以后的页面中获得出色的性能。例如:

(   SELECT name, id
    FROM _test1 -- conditions WHERE
    ORDER BY name DESC LIMIT 0, 30
)
UNION ALL
(   SELECT name, id
    FROM _test2 -- conditions WHERE
   ORDER BY name DESC LIMIT 0, 30
)
ORDER BY name DESC
LIMIT 10, 20
您基本上将每个子查询限制为给定页面上可能存在的行的子集。这样,您只需要从每个表中检索并合并20行,然后再确定返回哪10行。否则,服务器可能会从每个表中获取所有行,排序并合并它们,然后开始尝试查找正确的行

不过,我并不经常使用MySQL,所以我不能保证该引擎会按照我认为应该的方式运行:)


在任何情况下,一旦进入后面的页面,您仍然会合并越来越大的数据集。然而,我强烈认为UI不应该允许用户检索允许他们进入(例如)第5000页的一组记录。对于人类大脑来说,这些数据太多,无法一次找到所有有用的数据,因此需要进一步过滤。也许让他们看到前100页(或其他数字),但否则他们必须更好地限制结果。不过,这只是我的看法。

我怀疑问题不在于
联合所有
,而在于
排序。只有当简化的示例可以重现问题时,简化的示例才有用。如果这两个表中都没有where子句和名称索引,您能看到上面两个表的问题吗?如果您有两个表,并且需要这样的查询,那么它看起来更像是一个设计问题。对于
LIMIT 10,20
来说,优化并不困难,但是对于
LIMIT 5000,20
来说,如果不是不可能的话,这将是相当困难的。注释where是一种表示可能是条件或者可能不是条件的方式(列表中有一些搜索输入字段),但两者都很慢(可能我没有对此进行很好的解释)。问题是(我认为)产生联合体的数据量巨大,必须对其进行排序,并最终应用限制。@如果你是对的。问题是我无法更改结构的“遗留数据库”。我怀疑问题不在于
UNION ALL
,而在于
ORDER BY
。只有当简化的示例可以重现问题时,简化的示例才有用。如果这两个表中都没有where子句和名称索引,您能看到上面两个表的问题吗?如果您有两个表,并且需要这样的查询,那么它看起来更像是一个设计问题。对于
LIMIT 10,20
来说,优化并不困难,但是对于
LIMIT 5000,20
来说,如果不是不可能的话,这将是相当困难的。注释where是一种表示可能是条件或者可能不是条件的方式(列表中有一些搜索输入字段),但两者都很慢(可能我没有对此进行很好的解释)。问题是(我认为)产生联合体的数据量巨大,必须对其进行排序,并最终应用限制。@如果你是对的。问题是我无法更改结构的“遗留数据库”。在子查询中,您需要
限制0,30
,而不是
限制0,20
,但我在所有其他方面都同意。(
限制x,y
限制y偏移x相同)
谢谢。我认为语法是“开始”和“结束”,而不是“开始”和“返回的数字”。现在纠正它。是的,OP可能也这么想!在子查询中,您需要
限制0,30
而不是
限制0,20
,但我在所有其他方面都同意。(
限制x,y
限制y偏移x相同)
谢谢。我认为语法是“开始”和“结束”,而不是“开始”和“返回的数字”。现在纠正它。是的,OP可能也这么想!