【问题标题】:How to optimize a UNION with a final ORDER BY/OFFSET如何使用最终的 ORDER BY/OFFSET 优化 UNION
【发布时间】:2018-09-05 23:52:20
【问题描述】:

我在网页上(使用 datatable.js)得到了一个复杂的表格,它与 3 个不同的“来源”一起使用。这个数据表是前面分页的,后面没有。

我想把分页的服务器处理,我的请求有效,但我想优化它:

SELECT toto, titi
FROM
    (SELECT toto, titi
    FROM S1

    UNION

    SELECT toto, titi
    FROM S2

    UNION

    SELECT toto, titi
    FROM S3)
ORDER BY titi, toto
OFFSET 50 ROWS FETCH NEXT 50 ROWS ONLY

我的真实代码更复杂,但你在这里有我的问题的主要思想。

S1S2S3 可能各有 1 000 000 行,但最后我只需要 50 行,知道如何提高效率吗?

【问题讨论】:

  • 不确定您是否能够更快地完成此操作。你可以改用union all 吗?这不会删除重复项,但应该会稍微快一些...
  • 更好的方法是将每个选择查询中的查询限制为 50,并将它们合并。毕竟,再次将它们限制在 50 以内。
  • 是的 Muhammad,但我最后有一个 ORDER BY,所以我真的不知道要在 UNION 之前过滤哪一行。谢谢 sgeddes,我会做的。

标签: sql sql-server pagination union


【解决方案1】:

确保在所有三个表上都有索引,列有(titi, toto)

create index ix1 on s1 (titi, toto);
create index ix2 on s2 (titi, toto);
create index ix3 on s3 (titi, toto);

那么查询可能如下所示:

select * 
  from (
    select toto, titi from s1 order by titi, toto 
      fetch next (50 + 50) rows only
    union all
    select toto, titi from s2 order by titi, toto
      fetch next (50 + 50) rows only
    union all
    select toto, titi from s3 order by titi, toto
      fetch next (50 + 50) rows only
  ) x
  order by titi, toto
  offset 50 rows fetch next 50 rows only

无论如何,对于OFFSET 的高值,您的分页策略效率很低。尽管如此,我上面的查询可以有所作为。

对您的查询的主要改进是:

  • 分别在每个表上使用索引。
  • 使用UNION ALL 而不是UNION,因为它更有效。

【讨论】:

  • 对不起,但这不是一个解决方案,因为 ORDER BY 是全局的,表 S1、S2 和 S3 是不同的(您的代码只有一个表 S1)。
  • 感谢您的回答,它提供了很好的建议。但是,我的想法是,在真正的脚本中,我的“ORDER BY”是动态的(用户在界面上选择它)并且我至少有 10 列(将来可能会更多),所以我认为我不能真的会生成 10^10 个索引 :),它会消耗我的写作时间。此外,mb 再次没有真正回答我的问题:较小的 SELECT 的提取没有选择好的行,因为我想要 FINAL 表第二页的 50 行,这不一样(S1、S2 和 S3有不同的数据)。或者......我仍然没有得到“50 + 50”的技巧:)
  • 我想我现在明白了......我应该输入OFFSET 500 ROWS FETCH NEXT 50 ROWS ONLY 来做出改变并轻松理解它。我会试试的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2014-05-30
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
相关资源
最近更新 更多