在Oracle中,比SELECT COUNT(*) FROM sometable更快的替代方法

7 浏览
0 Comments

在Oracle中,比SELECT COUNT(*) FROM sometable更快的替代方法

我注意到在Oracle中,对于大型表来说,查询

SELECT COUNT(*) FROM sometable;

非常慢。看起来数据库实际上是逐行遍历并逐个递增计数器。我原本认为表中会有一个计数器记录表的行数。

那么,如果我想要在Oracle中检查表中的行数,最快的方法是什么?

0
0 Comments

在Oracle中,使用SELECT COUNT(*) FROM sometable来计算表中的行数是一种常见的方法。然而,这种方法在大型表中可能会导致性能问题。在多用户环境下,每个会话的计数器可能不同,因此数据库必须遍历每一行来计算准确的行数。这在实际应用中是不可行的,并且在大多数情况下,查询中会包含WHERE子句或JOIN语句,因此COUNT(*)的值对实际应用的价值有限。

为了加快查询速度,可以使用索引来计算行数。如果在一个NOT NULL列上创建了索引,Oracle将使用索引的行数而不是整个表的行数。在合适的关系模型中,所有的表都有一个主键,因此COUNT(*)将使用主键索引。

此外,如果存在位图索引,COUNT(*)也可以使用位图索引来计算行数,位图索引会包括NULL行的条目。

然而,即使在具有索引的情况下,当表非常大时,COUNT(*)仍然会花费一定的时间。在这种情况下,可以考虑一些替代方法,例如在材料化视图中记录结果,对样本进行COUNT,等等。

COUNT(*)查询的性能取决于表的大小和结构,以及查询中是否使用了索引。在处理大型表时,需要权衡准确性和性能之间的关系,如果只需要一个估计值,可以选择更快的方法。

0
0 Comments

问题的出现原因:

在Oracle中,使用SELECT COUNT(*) FROM sometable来获取表中行数的方法是常见且有效的。然而,当表非常大时,这种方法可能会非常慢,因为它需要扫描整个表来计算行数。因此,有时候需要寻找一种更快的替代方法来获取表中行数。

解决方法:

在Oracle中,有几种方法可以更快地获取表中行数的估计值。首先,可以通过对样本数据进行估算来获得粗略的估计值。可以使用SAMPLE子句来指定要使用的样本大小。例如,使用SAMPLE (1)表示使用整个表的1%作为样本数据。然后,通过将样本数据的行数乘以100来估算整个表的行数。如果需要更快的计算速度但是精度可以降低,可以减小样本大小,例如使用SAMPLE (0.1)来表示使用整个表的0.1%作为样本数据。同样,通过将样本数据的行数乘以1000来估算整个表的行数。此外,还可以使用SAMPLE BLOCK子句进行块级别的采样,例如使用SAMPLE BLOCK (1)来进行块级别的采样。

然而,需要注意的是,这些方法只适用于基本表,不能在子查询中使用SAMPLE子句。如果要在子查询中实现类似的概念,除了实际运行查询并计算返回记录数之外,唯一可以考虑的方法是使用Oracle的优化器统计信息。可以查看解释计划的顶层中的基数来估计子查询的行数,但这种方法只能提供数量级的估计,对于任何用例来说可能不是一个合理的替代方法。

0
0 Comments

在Oracle中,使用SELECT COUNT(*) FROM sometable查询表中记录数量的速度较慢。根据给出的内容,问题的出现原因可能是该查询语句执行时间较长,特别是对于大表而言。而解决方法是使用其他更快的替代方法来获取表中的记录数量。

一种更快的替代方法是使用以下查询语句:

SELECT NUM_ROWS FROM ALL_TABLES WHERE TABLE_NAME = 'TABLE_NAME_IN_UPPERCASE';

这种方法适用于大表,可以快速获取表的记录数量。

对于小到中等大小的表,可以使用以下查询语句:

SELECT COUNT(Primary_Key) FROM table_name;

需要确保table_name的格式为'TABLE_NAME'

需要注意的是,这些方法并不是实时更新的,具体取决于数据库的设置。在一个有8500万行的表中,使用ALL_TABLES查询记录数量只需3毫秒,而使用count(*)或count(primary_key)则需要3秒左右的时间。而在一个有52行的表中,使用ALL_TABLES、count(*)和count(primary_key)的执行时间相差不大。

如果在Oracle中需要获取表的记录数量,并且查询语句的执行速度较慢,可以考虑使用上述提到的更快的替代方法。

0