将最小 n 条记录限制为 Oracle SQL 中的输出

Posted

技术标签:

【中文标题】将最小 n 条记录限制为 Oracle SQL 中的输出【英文标题】:To Limit Minimum n records as Output in Oracle SQL 【发布时间】:2020-12-01 10:39:21 【问题描述】:

我有一个类似下面的查询,我将 emp 作为一个表格提供给方便参考。

原始查询:

select s.* from (select distinct emp.name from emp orderby emp.id order by emp.name) s
where rownum<=20;

问题:

emp 表非常庞大,包含数十亿行,还包含重复记录。上面的查询运行了 1 个多小时,耗尽了所有数据库资源。所以,为了优化上面的查询,我修改如下。

修改后的查询

select s.* from (select distinct emp.name from emp orderby emp.id where rownum<=20) order by s.name;

修改查询中的问题:

如果假设为前 20 条记录检索的名称相同,则 distinct 仅提供 1 条记录作为输出。但我在输出中至少需要 20 条记录。有没有办法实现?

请注意,由于各种原因,我们的数据库中不允许在 emp.name 上创建索引。

【问题讨论】:

【参考方案1】:

聚合和fetch 子句是否更有效?

select name
from emp
group by name
order by name
fetch first 20 rows only

【讨论】:

不,这又运行了 40 多分钟,耗尽了所有资源【参考方案2】:

使用select distinctgroup by 不会加快查询速度。他们处理整个结果集。

如果您实际上不需要绝对名字,您可以取样然后应用逻辑:

select distinct name
from (select e.name
      from emp
      where rownum < 1000000
     ) e
order by name
fetch first 20 rows only;

如果您确实需要按字母顺序排列的前 20 个名称,那么您需要在 name 上建立一个索引——或者一个单独的 names 表,其中包含所有不同的名称。我可能会建议您取消对行数的限制并将结果放入(临时?)表中 - 仅获取前 20 行几乎没有性能优势。

【讨论】:

以上是关于将最小 n 条记录限制为 Oracle SQL 中的输出的主要内容,如果未能解决你的问题,请参考以下文章

删除oracle 表中重复数据sql语句保留rowid最小的一条记录

限制从 Oracle 中的 SQL 查询返回的记录

如何能实现将oracle的查询结果排序后,只返回第一条记录

Oracle SQL 或 PLSQL 随负载扩展

Oracle通过一个字段的值将一条记录拆分为多条记录

SQL Server数据库用sql语句实现分页查询 (从M条数据开始,查找N条记录。sqlserver数据库。请举例说明。)