Cha*_*rns 5 performance oracle statistics count
我的应用程序通常需要准确但可能不完美的行数。十亿行的表经常会被频繁写入,所以“完美”是定义和时间的问题。
Microsoft SQL 保留了非常好的元数据,允许进行如下查询:
SELECT SUM(rows) FROM sys.partitions
WHERE object_id = object_id('TABLE_NAME')
AND index_id < 2;
Run Code Online (Sandbox Code Playgroud)
(还有其他具有不同元数据的方法)。这提供了近乎完美的行数,可能会忽略某些正在进行的事务或其他细节。这些技术适用于除最苛刻的情况之外的所有情况,并且几乎是即时的。
在 Oracle 中,我们可以使用统计信息:
SELECT num_rows
FROM all_tables
WHERE table_name = 'TABLE_NAME'
Run Code Online (Sandbox Code Playgroud)
这是不可靠的,因为如果完全收集了统计信息,根据 DBA 策略,它们通常已经过时。
我可以牺牲显着的准确性来使用采样来提高速度:
SELECT COUNT(*) * 1000 rc_sampled FROM lot_size SAMPLE(.1) SEED(42)
Run Code Online (Sandbox Code Playgroud)
然而,这是不准确的设计,还是相当慢(115秒在500M行测试),并且几乎是无用的,当应用程序不已经有一个行数的估计。在一个有 800 行的表上运行该 SQL 就像问,“那个糖果棒的价格是多少,给予或接受 75.00 美元?”)
Oracle 是否提供了一种实用的方法来获得任意表的准确、快速的行数,例如 Microsoft SQL 和其他提供的表?
Oracle 数据库在内部跟踪自上次收集统计信息以来表上受 DML/DDL 操作影响的行数。
我从来没有用过它来做任何重要的事情,但你可以尝试一下。首先将监控数据从内存刷新到底层表,这样就可以查询了(这也是周期性发生的):
exec dbms_stats.flush_database_monitoring_info;
Run Code Online (Sandbox Code Playgroud)
然后选择行数并通过插入/删除进行调整:
select
t.num_rows - i.deletes + i.inserts
from
user_tables t
join user_tab_modifications i on t.table_name = i.table_name
where
t.table_name = 'TABLE_NAME'
;
Run Code Online (Sandbox Code Playgroud)
当然,这并不是 100% 准确,例如,如果数据库在自动刷新之前重新启动,该信息就会丢失。
但是您应该拥有有关更改的表的最新统计信息。