0

I want a query that selects the number of rows in each table but they are NOT updated statistically .So such query will not be accurate:

select table_name, num_rows from user_tables

i want to select several schema and each schema has minimum 500 table some of them contain a lot of columns . it will took for me days if i want to update them .

from the site ask tom he suggest a function includes this query

'select count(*) from ' || p_tname INTO l_columnValue;

such query with count(*) is really slow and it will not give me fast results.
Is there a query that can give me how many rows are in table in a fast way ?

4

3 回答 3

2

完全披露:我最初提出了一个查询,该查询专门计算 (a) 已编入索引且 (b) 不为空的列。@AlexPoole 和 @JustinCave 指出(请参阅下面的评论)Oracle 无论如何都会优化 aCOUNT(*)来做到这一点。因此,这个答案已经发生了重大变化。


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

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

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

于 2013-05-13T17:38:16.903 回答
2

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

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

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

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

这似乎是一件很奇怪的事情——要么你的应用程序使用表,在这种情况下,即使它是空的,删除它也会破坏一些东西;或者没有,在这种情况下,它是否有(可能是多余的)并不重要,并且无论如何都可以删除它。如果您认为可能存在混淆,那听起来您的源(包括 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;

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

于 2013-05-13T17:58:49.567 回答
0

您可以制作一个表格来保存每个表格的计数。然后,为您计算的每个更新主表的表设置一个触发器以在 INSERT 上运行。

您还需要包含一个 DELETE 触发器。

于 2013-05-13T17:32:44.813 回答