Database 我们如何优化oracle数据库?

Database 我们如何优化oracle数据库?,database,oracle,database-design,oracle9i,Database,Oracle,Database Design,Oracle9i,我们有一个Oracle 9i数据库,有7个表,每个表有1500多万条记录。表之间没有关系,即没有外键 下面是其中一个表的示例 CREATE TABLE GSS.SHOWPD ( INSERVID VARCHAR2(7 CHAR) NOT NULL, CAGEPOS VARCHAR2(8 CHAR) DEFAULT NULL, DETAILEDSTATE VARCHAR2(100 CHAR)

我们有一个Oracle 9i数据库,有7个表,每个表有1500多万条记录。表之间没有关系,即没有外键

下面是其中一个表的示例

CREATE TABLE GSS.SHOWPD
(
  INSERVID          VARCHAR2(7 CHAR)            NOT NULL,
  CAGEPOS           VARCHAR2(8 CHAR)            DEFAULT NULL,
  DETAILEDSTATE     VARCHAR2(100 CHAR)          DEFAULT NULL,
  FAILEDMB          NUMBER                      DEFAULT NULL,
  FREECHUNK         NUMBER                      DEFAULT NULL,
  FREEMB            NUMBER                      DEFAULT NULL,
  FWREV             VARCHAR2(100 CHAR)          DEFAULT NULL,
  FWSTATUS          VARCHAR2(100 CHAR)          DEFAULT NULL,
  AID               NUMBER                      DEFAULT NULL,
  LDA               VARCHAR2(100 CHAR)          DEFAULT NULL,
  MANUF             VARCHAR2(100 CHAR)          DEFAULT NULL,
  AMODEL            VARCHAR2(4000 CHAR)         DEFAULT NULL,
  NODEWWN           VARCHAR2(64 CHAR)           DEFAULT NULL,
  NRMUNUSEDFAIL     VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUNUSEDFREE     VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUNUSEDUNAVAIL  VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUSEDFAIL       VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUSEDOK         VARCHAR2(100 CHAR)          DEFAULT NULL,
  AORDER            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHA0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHA1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHB0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHB1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTA0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTA1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTB0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTB1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  RDCERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  REUERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  SERIAL            VARCHAR2(100 CHAR)          DEFAULT NULL,
  SIZEMB            NUMBER                      DEFAULT NULL,
  SPARECHUNK        VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPAREMB           NUMBER                      DEFAULT NULL,
  SPEEDKRPM         VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDFAIL     VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDFREE     VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDUNINIT   VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUSEDFAIL       VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDOK       VARCHAR2(100 CHAR)          DEFAULT NULL,
  STATE             VARCHAR2(100 CHAR)          DEFAULT NULL,
  TEMPDEGC          NUMBER                      DEFAULT NULL,
  TOTALCHUNK        VARCHAR2(100 CHAR)          DEFAULT NULL,
  ATYPE             VARCHAR2(100 CHAR)          DEFAULT NULL,
  UNAVAILABLEMB     NUMBER                      DEFAULT NULL,
  VOLUMEMB          NUMBER                      DEFAULT NULL,
  WRCERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  WRUERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  COMMANDTIMESTAMP  TIMESTAMP(6)                DEFAULT NULL  NOT NULL,
  FETCHTIMESTAMP    TIMESTAMP(6)                DEFAULT NULL  NOT NULL
)
请注意,INSERVID可以是1400种类型之一。因此,有可能会有1400张桌子,每一张都专门用于一个inserv。这样做是不是很疯狂?我想知道

我们迭代inservs的数量,并对它们运行所有查询。现在我们正在清除数据,所以我们预计不会超过1500万条记录

1) 我们在查询中使用了distinct,因此需要进行完整的表扫描。Oracle执行计划显示我们正在进行完全的表扫描

select distinct(inservid),commandtimestamp from statpd order by commandtimestamp desc;

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |   665 | 13300 | 79488 |
|   1 |  SORT UNIQUE         |             |   665 | 13300 | 69088 |
|   2 |   TABLE ACCESS FULL  | STATPD      |  4128K|    78M| 19406 |
--------------------------------------------------------------------
Note: cpu costing is off
10 rows selected.
2) 每个表都有一个inserv id索引。它有助于降低查询成本,我们还可以做些什么?有什么让事情变得更快的提示/技巧吗

3) 如果我们将针对每个表运行的sql查询作为针对每个表运行的并行脚本,这有意义吗。这会导致更快的完成吗

4) 我们有足够的RAM在内存中加载整个数据库。有没有可能通过ORACLE做到这一点

提前感谢

1-2)在
(inservid,commandtimestamp)
上有索引将用(快速)完整索引扫描替换完整表扫描,因为两列中的一列不是空的(因此DB可以使用索引而不是表)。这应该比全表扫描快,但将读取所有15+M行索引项

使用预计算表(例如快速刷新物化视图)可以获得更快的响应时间,在这种情况下,可能会对表上的DML操作造成性能影响(insert/update/delete会更慢)

3) 如果您还有一些IO带宽,让查询并行运行将给您带来一些好处。现在,您的完整表扫描可能会从磁盘读取很多行。除非您的表驻留在物理上分离的设备上,否则并行所带来的收益将是最小的


4) RAM中的加载主要是在Oracle中自动完成的:即,在大多数情况下,Oracle在将频繁访问的数据放入内存方面做得很好。

第4部分,这通常不是必需的。在9i中,您可以设置一个特殊的“保留”缓冲池,以尝试将索引保留在内存中。(但由于Oracle现在还没有提供支持,现在可能不是开始试验您尚未使用的功能的好时机)

您的客户端是否在本地计算机上,如果不是,客户端可能会受益于11g功能客户端(side)结果缓存,以最小化数据库服务器往返

7.6.2.1客户端结果缓存的工作方式 客户端结果缓存存储最外层查询的结果,即OCI应用程序定义的列。子查询和查询块不缓存

图7-4显示了一个具有数据库登录会话的客户端进程。此客户端进程在客户端进程中运行的多个应用程序会话之间共享一个客户端结果缓存。如果第一个应用程序会话运行查询,则它从数据库检索行并将其缓存在客户端结果缓存中。如果其他应用程序会话ns运行相同的查询,然后还从客户端结果缓存中检索行

我同意文森特的观点

由2)您有一个长的行-所以它可能有一个更大的数据库块大小-16Kb或32Kb的好 在您的表上尝试压缩可能是值得的。还要检查您的db\u文件\u多块\u读取\u计数。可能是它的一部分-将它分发到尽可能多的驱动器上


3) 您可以使用parallel hint来查看结果。

您的数据模型已损坏。您可以提供有关您运行的查询的更多详细信息吗?添加索引只会在一定程度上帮助您。

我认为distinct本身不会导致全表扫描。@David发布执行计划输出以获得更好的效果understanding@David请看一看在执行计划输出中确定了解更多第(4)部分-是的,Oracle有一个内存中的数据库产品-在上有一个索引(inservid,commandtimestamp)在我们的经验中,实际增加了执行计划的成本感谢额外的投入…需要探索:)thanks@Ankur古普塔:创建索引,分析表和索引,并衡量哪一个是最快的(运行两次查询,一次使用完整扫描,另一次使用索引路径,您可能需要提示查询以强制db使用完整扫描)。此方法比比较优化器成本更可靠。我们使用9i,无法升级到10/11…必须保持不变。Oracle 9i版本2(9.2.0)扩展支持结束:2010年7月30日…(或者他们是否扩展了…)感谢2)将投入时间了解我如何做到这一点,并了解它如何提高我的执行速度…谢谢。。。