【问题标题】:ORACLE table performance basicsORACLE 表性能基础知识
【发布时间】:2014-10-14 19:14:23
【问题描述】:

完全是 Oracle DBA 的新手,但仍在尝试将 SQL Server DB (2008R2) 迁移到 Oracle(11g - 总 DB 大小仅为 ~20Gb)...

我的最大单表(约 3000 万行)存在重大问题。表的粗略结构是:

CREATE TABLE TableW (
  WID NUMBER(10,0) NOT NULL,
  PID NUMBER(10,0) NOT NULL,
  CID NUMBER(10,0) NOT NULL
  ColUnInteresting1 NUMBER(3,0) NOT NULL,
  ColUnInteresting2 NUMBER(3,0) NOT NULL,
  ColUnInteresting3 FLOAT NOT NULL,
  ColUnInteresting4 FLOAT NOT NULL,
  ColUnInteresting5 VARCHAR2(1024 CHAR),
  ColUnInteresting6 NUMBER(3,0) NOT NULL,
  ColUnInteresting7 NUMBER(5,0) NOT NULL,
  CreatedDate  DATE NOT NULL,
  ModifiedDate DATE NOT NULL,
  CreatedByUser VARCHAR2(20 CHAR),
  ModifiedByUser VARCHAR2(20 CHAR)
);

ALTER TABLE TableW ADD CONSTRAINT WPrimaryKey PRIMARY KEY (WID)
ENABLE;

CREATE INDEX WClusterIndex ON TableW (PID);
CREATE INDEX WCIDIndex ON TableW (CID);

ALTER TABLE TableW ADD CONSTRAINT FKTableC FOREIGN KEY (CID) 
REFERENCES TableC (CID) ON DELETE CASCADE
ENABLE;
ALTER TABLE TableW ADD CONSTRAINT FKTableP FOREIGN KEY (PID) 
REFERENCES TableP (PID) ON DELETE CASCADE
ENABLE;

通过一些基础测试,似乎一个简单的“从 TableW WHERE PID=13455 中删除”需要花费大量时间(~880 秒)来执行应该是快速删除(~350 行)的操作。 [通过 SQL Developer 运行查询]。

通常,此表的性能明显低于其 SQL 等效表。在 SQL Server 下没有任何问题,与 SQL 相比,此表及其周围的表结构对于 Oracle 来说是合理的。

我的问题是我找不到有用的诊断集来开始寻找问题所在。非常感谢任何查询/链接。

[以上是一个帮助请求,基于这样的假设:从一个有 3000 万条记录的表中删除 350 行应该不需要 10 分钟,而 SQL Server 需要

编辑: 正在执行迁移:

1 In SQL developer:
    - Create Oracle User, tablespace, grants etc AS Sys 
    - Create the tables, sequences, triggers etc AS New User
2 Via some Java:
    - Check SQL-Oracle structure consistency
    - Disable all foreign keys
    - Move data (Truncate destination table, Select From Old, Insert Into New)
    - Adjust sequences to correct starting value
    - Enable foreign keys

【问题讨论】:

  • Oracle中是否存在索引碎片之类的东西?如果您在加载数据之前创建了所有索引并且之后没有重建它们,那么WClusterIndex 索引很可能会严重碎片化,以至于无法使用。
  • 这就是我正在考虑的事情 - 请查看我的编辑,看看迁移中是否有任何明显的错误。
  • 我根本不了解 Oracle,但您始终可以尝试删除并重新创建索引。任何 ETL 的最佳实践是在加载之前删除索引(当然是在目标端)并在之后创建它们。它不仅速度更快,而且减少了碎片化。
  • 您是否收集了有关表格的统计信息? exec dbms_stats.gather_table_stats(user, 'TABLE_W');
  • @MarcoBaldelli - 是的,它对执行时间没有影响。

标签: sql-server oracle11g migration database-administration


【解决方案1】:

如果你问我们如何提高性能,那么有几种方法可以提高它:

并行 DML 会消耗您执行操作所需的所有资源。 Oracle 运行多个线程来完成操作。其他会话必须等待操作结束,因为系统资源很忙。

分区可让您立即排除旧部分。例如,您的表存储 2000 年到 2014 年的数据。很可能您不需要旧记录,因此您可以将表拆分为多个分区并排除最旧的分区。

【讨论】:

  • 提高性能是第二步——首先我必须知道我迁移的结构是否有问题......
  • 有什么问题?你运行你的脚本了吗?您发现任何错误吗?
  • 在初始问题中添加的注释:以上是基于假设从具有 3000 万条记录的表中删除 350 行的时间不超过 10 分钟的请求。
  • 我们怎么知道呢?您可以在具有 32MB 内存的 Intel celeron 处理器上运行,也可以在其中一台超级计算机上运行它。你必须尝试然后你会发现它是否需要超过10分钟
  • 查看问题说明:我正在从 SQL Server 迁移到 Oracle。我正在运行查询'DELETE FROM TableW WHERE PID=13455' 这个查询在 SQL Server 下运行良好(在 10 分钟内运行)我如何在下面诊断问题甲骨文?
【解决方案2】:

检查正在执行 DELETE 的会话的等待事件。这会告诉你你的主要瓶颈是什么。

并附和上面 Marco 的评论 - 确保您的表统计信息是最新的 - 这将有助于优化器制定一个好的计划来为您运行这些查询。

【讨论】:

  • 表统计信息是最新的,给定会话的 V$SESSION_EVENT 中的最大值(数量和总时间)用于“db 文件分散读取”(不包括“来自客户端的 SQL*NET 消息” )。这意味着大部分时间都花在阅读整个表格上,不是吗?如果列被索引,为什么会这样?
【解决方案3】:

更新所有内容(以防其他人发现):

找到解决方案的正确问题是:您有哪些表引用了这个?

问题是另一个表(我们称之为 TableV)使用 WID 作为外键,但是 TableV 中的 WID 列没有被索引。这意味着对于 TableW 中的每条记录删除,都必须在整个 TableV 中搜索要删除的关联记录。由于 TableV 的行数超过 300 万行,删除 TableV 中 350 行的小集合意味着 Oracle 服务器尝试读取的行总数超过 10 亿行。

在 TableV 中添加到 WID 的单个索引,删除语句现在需要

感谢所有的 cmets - 学习了很多 Oracle 内部工作!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 2018-05-25
    • 2014-11-28
    • 2014-02-14
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多