Sql 如何从包含一百万条记录的数据库中选择第一个“N”条记录?

Sql 如何从包含一百万条记录的数据库中选择第一个“N”条记录?,sql,oracle,sorting,sql-order-by,Sql,Oracle,Sorting,Sql Order By,我有一个oracle数据库,里面有一百万条记录。我正在尝试编写一个SQL查询,根据特定条件返回数据库中的前N条排序记录,比如100条记录 SELECT * FROM myTable Where SIZE > 2000 ORDER BY NAME DESC 然后以编程方式选择前N条记录 这种方法的问题是: 查询结果为50万 记录和按名称排序的原因 所有要按名称降序排序的记录。这种分类要花很多时间。将近30-40秒。如果我省略orderby,只需要1秒。 在我感兴趣的那种之后 只有前1

我有一个oracle数据库,里面有一百万条记录。我正在尝试编写一个SQL查询,根据特定条件返回数据库中的前N条排序记录,比如100条记录

SELECT * 
FROM myTable 
Where SIZE > 2000 
ORDER BY NAME DESC
然后以编程方式选择前N条记录

这种方法的问题是:

查询结果为50万 记录和按名称排序的原因 所有要按名称降序排序的记录。这种分类要花很多时间。将近30-40秒。如果我省略orderby,只需要1秒。 在我感兴趣的那种之后 只有前100条记录。因此,对完整记录进行排序是没有用的。 我的问题是:

是否可以在中指定“N” 查询本身?所以这种排序只适用于N条记录,查询速度会更快。 SQL中有没有更好的方法来改进查询排序 仅N个元素,并快速返回 时间 添加以下内容:

 AND rownum <= 100
到您的WHERE子句

然而,这并不能满足你的要求

如果您想要选取100个随机行,对它们进行排序,然后返回它们,那么您必须首先制定一个没有ORDER BY的查询,然后将其限制为100行,然后从中选择并进行排序

这可能会起作用,但不幸的是,我没有可供测试的Oracle服务器:

SELECT *
FROM (
    SELECT *
    FROM myTable
    WHERE SIZE > 2000
      AND rownum <= 100
    ) x
ORDER BY NAME DESC
但是请注意这里的随机部分,你是说给我100行大小>2000的行,我不在乎哪100行

这真的是你想要的吗


不,实际上不会得到随机结果,因为每次查询服务器时,结果都会发生变化,但查询优化器会控制您。如果该表的数据加载和索引统计信息随时间而变化,那么在某个时候,您可能会得到与上一次查询不同的数据。

如果您的目的是查找100个随机行,然后对它们进行排序,那么这是正确的。如果我认为您希望前100行按名称排序,而丢弃其他行,则可以构建如下查询:

SELECT * 
  FROM (SELECT * 
          FROM myTable 
         WHERE SIZE > 2000 ORDER BY NAME DESC) 
 WHERE ROWNUM <= 100
编辑:仅添加和rownum显示如何根据您的Oracle版本选择前N行

从Oracle 9i开始,等级和 稠密秩函数可用于 确定前N行。示例:

根据以下内容获得前10名员工: 他们的薪水

从“选择”中选择“珐琅”、“萨尔” 艾娜,萨尔,萨尔的排名高于订单 描述sal_等级
在emp中,sal_rank的问题是每次运行查询时都会进行排序。如果已排序列被声明为非空,则可以通过使用索引来消除排序操作—优化程序可以使用索引来消除排序操作


如果该列可为空,则仍然可以通过向查询添加NOTNULL谓词,或添加基于函数的索引并相应修改ORDER by子句来实现。

仅供参考,在Oracle 12c中,可以使用FETCH子句完成此任务。您可以查看有关此问题的示例和其他参考链接。

谢谢您的回答。我的问题不是随机得到100。我想得到前100条已排序的记录。例如:如果记录为1,5,8,2,14,3,6,7。如果我想要3条记录,那么答案将是1,2,3,然后你确实想先对它们进行排序,如果对一百万行进行排序需要很多时间,那将不会有多大帮助。你所要做的就是避免检索网络上的所有行,排序仍然必须运行。然而,Oracle足够聪明,可以保留前100个结果。如果下一行在该100之外,它将丢弃该行。这样,它就不必对整个事情进行排序。这是打开的,而不是在日志n上
SELECT /*+ FIRST_ROWS*/* FROM myTable WHERE SIZE > 2000 ORDER BY NAME DESC