代码之家  ›  专栏  ›  技术社区  ›  aJ.

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

  •  8
  • aJ.  · 技术社区  · 15 年前

    我有一个oracle数据库,里面有一百万条记录。我试图编写一个SQL查询,根据特定条件从数据库返回第一个“N”排序记录(比如100条记录)。

    SELECT * 
    FROM myTable 
    Where SIZE > 2000 
    ORDER BY NAME DESC
    

    然后以编程方式选择前N条记录。

    这种方法的问题是:

    • 记录和“按名称排序”原因
    • 在我感兴趣的那种之后 只有前N(100)条记录。因此,对完整记录进行排序是没有用的。

    我的问题是:

    1. 是否可以在中指定“N”
    2. SQL中有没有更好的方法来改进查询排序 仅N个元素,并快速返回 时间
    5 回复  |  直到 15 年前
        1
  •  19
  •   Community Egal    7 年前

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

    SELECT * 
      FROM (SELECT * 
              FROM myTable 
             WHERE SIZE > 2000 ORDER BY NAME DESC) 
     WHERE ROWNUM <= 100
    

    优化器将理解这是一个TOP-N查询,并且能够在NAME上使用索引。它不必对整个结果集进行排序,它只需从索引末尾开始向后读取,然后在100行之后停止。

    您还可以向原始查询添加一个提示,让优化器知道您只对第一行感兴趣。这可能会生成类似的访问路径:

    SELECT /*+ FIRST_ROWS*/* FROM myTable WHERE SIZE > 2000 ORDER BY NAME DESC
    

    只是加上 AND rownum <= 100 之前

        2
  •  5
  •   IanH    15 年前

    This 显示如何根据您的Oracle版本选择前N行。

    稠密的_RANK()函数可用于 确定前N行。示例:

    根据以下内容获得前10名员工:

    从中选择珐琅、sal(选择 ename,sal,RANK()结束(sal命令) DESC)sal_秩 来自emp)其中sal_排名<=10;

    选择前10名的员工 薪水

    ename,sal,稠密秩()超过(顺序 来自emp)其中sal__排名<=10;

    解释了两者之间的区别 here

        3
  •  4
  •   Lasse V. Karlsen    15 年前

    添加以下内容:

     AND rownum <= 100
    

    到您的WHERE子句。

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

    工作正常,但不幸的是,我没有可供测试的Oracle服务器:

    SELECT *
    FROM (
        SELECT *
        FROM myTable
        WHERE SIZE > 2000
          AND rownum <= 100
        ) x
    ORDER BY NAME DESC
    

    但请注意“随机”部分,您的意思是“给我100行大小大于2000的,我不在乎哪100行”。

    这真的是你想要的吗?

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

        4
  •  0
  •   Jeffrey Kemp    15 年前

        5
  •  0
  •   Muntasir    8 年前

    仅供参考,在Oracle 12c中,可以使用 FETCH here 有关此问题的示例和其他参考链接。