【问题标题】:query on the first n rows from large table without checking all rows -oracle sql查询大表的前 n 行而不检查所有行 -oracle sql
【发布时间】:2017-04-25 10:43:37
【问题描述】:

每个查询都在我非常大的表上花费大量时间。出于测试目的,我希望对表的前几行实施查询。例如:在从 ROWNUM=1 的表中选择 * 中,将对所有行进行检查,即 ROWNUM 是否为 1。但我想测试几行查询只是为了节省时间。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    如果你只想选择前 n 行,那么你必须使用 -

    SELECT * 
    FROM TABLE
    WHERE ROWNUM <= N;
    

    【讨论】:

    • 我认为是WHERE ROWNUM &lt;= N;,否则是 (N-1) 行。
    • 我怀疑在执行此查询时,是否会检查表的所有行,即他们的 ROWNUM 是否小于 N?如果是这样的话,那么大桌子仍然需要很多时间
    • 也许 oracle 已经对此进行了优化。去尝试一下。您还可以使用 ROWNUM 创建附加列更新并为该列创建索引
    • 不,所有行都不会检查。 ORACLE 为每一行分配一个虚拟值,并将开始获取行,当它到达 =N 时,立即停止并显示 o/p。
    【解决方案2】:

    rownum 是一个伪列,它不存在于表记录中,并且在查询的谓词(where 子句)阶段完成后在运行时分配。因此,只有第一个查询返回结果

    select * from hr.employees where employee_id >190 and rownum<2;-- Will return one row
    select * from hr.employees where employee_id >190 and rownum>2;-- Won't return any resultset
    select * from hr.employees where employee_id >190 and rownum=3;-- Won't return any resultset
    

    最后两个查询未返回结果集的原因是,一旦谓词 (employee_id >190) 完成并将 rownum 分配给第一行,然后 for (2 query rownum>2) 1>2 返回 false 和 for (3 query rownum=3) 1=3 返回false所以不返回数据。

    谢谢 安迪

    【讨论】:

      【解决方案3】:

      为您的测试查询创建一个迷你测试表怎么样?

      create table my_test_table as select * from big_table where rownum <= n;
      

      现在你可以运行类似的东西

      select count(*) from my_test_table where color='red';
      

      然后将该结果除以n,以估计您的大数据库中有多少行有color='red'。当然,请注意,您可能会非常不走运(即您的小桌子可能是整个桌子人口的一个较差样本),在这种情况下,您可能只需增加 n 以获得更好的样本。

      如果您不能或不想创建新表,您当然可以只使用嵌套查询:

      select * from (select * from big_table where rownum <= n)
        where <condition>;
      

      【讨论】:

        猜你喜欢
        • 2016-07-17
        • 1970-01-01
        • 1970-01-01
        • 2016-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-24
        • 2014-06-28
        相关资源
        最近更新 更多