一种快速查询,用于选择每个表中的行数

时间:2013-05-13 17:28:55

标签: oracle

我想要一个选择每个表中行数的查询  但它们没有统计更新。所以这样的查询不准确:

  

从user_tables选择table_name,num_rows为

我想选择几个架构,每个架构至少有500个表,其中一些包含很多列。如果我想更新它们将花费我几天。

来自网站ask tom

他建议功能包含此查询

  

'选择计数(*)             来自'|| p_tname INTO l_columnValue;

这种带有count(*)的查询非常慢,并且不会给我快速的结果 是否有一个查询可以快速地给我表中有多少行?

3 个答案:

答案 0 :(得分:2)

完全披露:我最初建议的查询专门计算(a)索引和(b)非空的列。 @AlexPoole和@JustinCave指出(请参阅下面的评论)Oracle将优化COUNT(*)来执行此操作。因此,这个答案已经发生了重大变化。


有一个很好的解释here,为什么User_Tables不应该用于准确的行计数,即使统计数据是最新的。

如果您的表具有可用于通过索引扫描而不是表扫描来加速计数的索引,Oracle将使用它们。这将使计数更快,但不是任何方式瞬间。也就是说,这是我知道获得准确计数的唯一方法。

要检查空(零行)表,请使用Alex Poole发布的答案。

答案 1 :(得分:2)

您在评论中说要删除(删除?)空表。如果您不想要精确计数,但只想知道表是否为空,则可以执行快捷计数:

select count(*) from table_name where rownum < 2;

优化器将在到达第一行时停止 - 执行计划显示'计数停止键'操作 - 因此速度很快。对于一个空表,它将返回零,对于包含任何数据的表,它将返回一个 - 您不知道有多少数据,但您似乎并不关心。

当然,在计数和下降之间仍然存在轻微的竞争条件。

这似乎是一件非常奇怪的事情 - 要么你的应用程序使用表格,在这种情况下,即使它是空的,它也会破坏它;或者它没有,在这种情况下它是否具有(可能是多余的)并且无论如何都可以被丢弃。如果您认为可能存在混淆,那听起来像您的源(包括DDL)控件需要一些工作吗?


要检查两个模式中的任何一个表是否有一行,只需从两个表中计数;要么是工会:

select max(c) from (
    select count(*) as c from schema1.table_name where rownum < 2
    union all
    select count(*) as c from schema2.table_name where rownum < 2
);

...或greatest和两个子选项,例如:

select greatest(
    (select count(*) from schema1.table_name where rownum < 2),
    (select count(*) from schema2.table_name where rownum < 2)
) from dual;

如果任何一个表有任何行,则返回一个,并且只返回零,并且它们都是空的。

答案 2 :(得分:0)

您可以创建一个表来保存每个表的计数。然后,为INSERT上的每个表设置一个触发器,以便更新主表。

您还需要包含DELETE的触发器。