2

我试图count(*) 从表中获取该表,该表有近 700 万条记录,并且需要一个多小时才能返回结果。

此外,该表有 153 列,其中为第 123 列创建了索引,因此尝试并行运行以下查询,但没有帮助。

select /*+ parallel (5) */ count(123) from <table_name>

请建议是否有其他方法。

当我desc在 Toad 中的表上运行时,索引选项卡的值为 no。的行。知道该值如何在那里更新吗?

4

3 回答 3

4

提几个问题:

  1. “select count(*) from table”要使用索引,索引列必须不可为空,或者索引必须是位图类型。
  2. 如果已知列中没有空值但没有非空约束,则使用“select count(*) from table where column_name is not null”。
  3. 当然,扫描索引比扫描表更有效,但是有这么多的表列,你可能在那里没问题。
  4. 如果您真的想要并行索引扫描,请使用 parallel_index 提示,而不是并行。但是只有 700 万行,您可能不需要并行性。
  5. 您需要检查执行计划以查看是否正在使用索引和/或并行查询。
  6. 如果您可以使用估计的行数,请考虑使用 sample 子句:例如“select 1000*count(*) from table sample(0.1)”
于 2013-06-26T16:49:39.173 回答
2

计算大表的行数需要很长时间。这是自然的。一些 DBMS 存储记录的数量,但是,这种 DBMS 限制了并发性。它应该在对表进行 DML 操作之前锁定整个表。(整个表锁是正确更新计数所必需的。)

ALL_TABLES.NUM_ROWS(or ) 中的值USER_TABLES.NUM_ROWS只是analyze table ...ordbms_stats.gather_table_stats过程生成的统计信息。它不准确,不是实时信息。

如果您不需要确切的行数,可以使用统计信息。但是,您不应该依赖它。它由 Oracle 优化器使用,但不应在应用程序中使用。

我不确定为什么你必须计算表格的行数。如果您在不经常运行的批处理程序中需要它,您可以对表进行分区以增加并行度。如果您需要在线程序中的计数,您应该找到一种不使用计数的方法。

于 2013-06-24T07:41:11.140 回答
0
select /*+ parallel (5) */ 

并行度似乎是奇数。嗯,很明显 5 是一个奇数,这很奇怪。DoP 应该是 2 的倍数(更多信息见下文)。

无论如何,您有理由使用并行查询吗?您是否至少有五个备用处理器?如果不是,那么管理 PQ 从站的开销很有可能至少会导致性能下降。


为什么 DOP = n*2?有一个基于队列理论的既定启发式方法,即同时运行两个以上的批处理作业会导致性能下降。 了解更多。 (我认为排队论实际上建议使用 1.8 的数字,但由于数据库作业通常受 I/O 或磁盘约束,我们通常可以使用 2。)

我最初说“2 的幂”,但这主要是因为多核服务器往往有多个 CPU,这是 2 的幂,但 2 的倍数更准确,因为有些盒子有 12 个 CPU 或其他数字。

现在,如果我们有一个 64 核的机器,5 或 37 的 DOP 就可以了,因为我们有足够的 CPU 来同时运行那么多线程。但是如果我们有一个小的四核盒子,那么只有 2、4 或 8 个才有意义,因为只有这些值才能确保在所有四个处理器上均匀分配工作。在四核机器上运行五个线程意味着一个 CPU 将比其他三个 CPU 做更多的工作;有可能需要更长的时间才能完成,让其他三个奴隶等待。所以DOP=5实际上可以导致比 更大的经过时间DOP=4

DOP=n*2只是一个经验法则,而不是一成不变的。然而,它是基于合理的推理,我们应该知道为什么我们要做一些不同的事情。显然,我们应该进行一些实验来确认我们选择了正确的 DOP(无论我们选择什么值)。

于 2013-06-26T16:31:07.113 回答