我的应用程序通常需要准确但可能不完美的行数。十亿行的表经常会被频繁写入,所以“完美”是定义和时间的问题。
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 允许主键具有重复值和空值。使用此功能并不是一个特别好的主意,但它意味着大多数开发人员认为主键的某些保证(非空、唯一)并不是真正的保证。
CREATE TABLE oracle_guarantees (
ID NUMBER(9,0),
NAME VARCHAR2(50 BYTE),
breed NVARCHAR2(100)
);
INSERT INTO oracle_guarantees VALUES (1, 'Fuzz Head', 'Tabby');
INSERT INTO oracle_guarantees VALUES (2, 'Fluffy Thing', 'Mix');
INSERT INTO oracle_guarantees VALUES (2, 'Fluffy Thing', 'Mix');
INSERT INTO oracle_guarantees VALUES (3, 'Tiger', 'Tabby');
INSERT INTO oracle_guarantees VALUES (4, 'Fur Beast', 'Bengal');
INSERT INTO oracle_guarantees VALUES (5, 'Karate', 'Japanese Bobtail');
INSERT INTO oracle_guarantees VALUES (6, 'Chairman Meow', 'Chinese Harlequin');
INSERT INTO oracle_guarantees VALUES (NULL, 'No Cat', 'No breed');
CREATE …
Run Code Online (Sandbox Code Playgroud)