远程数据库的表超过20个索引的影响

简介: 昨天同事参加了一个研讨会,有提到一个案例。一个通过dblink查询远端数据库,原来查询很快,但是远端数据库增加了一个索引之后,查询一下子变慢了。 经过分析,发现那个通过dblink的查询语句,查询远端数据库的时候,是走索引的,但是远端数据库添加索引之后,如果索引的个数超过20个,就会忽略第一个建立的索引,如果查询语句恰好用到了第一个建立的索引,被忽略之后,只能走Full Table Scan了。

昨天同事参加了一个研讨会,有提到一个案例。一个通过dblink查询远端数据库,原来查询很快,但是远端数据库增加了一个索引之后,查询一下子变慢了。

经过分析,发现那个通过dblink的查询语句,查询远端数据库的时候,是走索引的,但是远端数据库添加索引之后,如果索引的个数超过20个,就会忽略第一个建立的索引,如果查询语句恰好用到了第一个建立的索引,被忽略之后,只能走Full Table Scan了。

听了这个案例,我查了一下,在oracle官方文档中,关于Managing a Distributed Database有一段话:


Several performance restrictions relate to access of remote objects:

Remote views do not have statistical data.

Queries on partitioned tables may not be optimized.

No more than 20 indexes are considered for a remote table.

No more than 20 columns are used for a composite index.



说到,如果远程数据库使用超过20个索引,这些索引将不被考虑。这段话,在oracle 9i起的文档中就已经存在,一直到12.2还有。

那么,超过20个索引,是新的索引被忽略了?还是老索引被忽略了?如何让被忽略的索引让oracle意识到?我们来测试一下。

初始化测试表

d0a9f3ed2c6e757063644c2807aa015220592055

可以看到,远程表有27个字段,目前还只是在前20个字段建立了索引,且第一个字段是主键。本地表,有6个字段,6个字段都建索引。

第一轮测试,远程表上有20个索引

测试场景1:

在远程表20索引的情况下,本地表和远程表关联,用本地表的第一个字段关联远程表的第一个字段:

32e7cb4946abecac0a462f5602740f4b14be267e

我们可以看到,对于远程表的执行计划,这是走主键的。

测试场景2:

在远程表20索引的情况下,本地表和远程表关联,用本地表的第一个字段关联远程表的第20个字段:

77d14826f4ae77491eb2ab4e458b5ff7778f5785

我们可以看到,对于远程表的执行计划,这是走索引范围扫描的。

测试场景3:

在远程表20索引的情况下,本地表和远程表关联,用本地表的第2个字段关联远程表的第2个字段:

3b97f0a3e516df32ed5ba03b6e2e1952af7fd93f

我们可以看到,对于远程表的执行计划,这是走索引范围扫描的。

测试场景4:

在远程表20索引的情况下,本地表和远程表关联,用本地表的第2个字段关联远程表的第20个字段:

43af1b2e5cb7422baef24cb36dbe63675cdf1566

我们可以看到,对于远程表的执行计划,这是走索引范围扫描的。

建立第21个索引

5815515a2382d5badbc0db2e8d0ac4681759fd4d

重复上面4个测试

测试场景1:

6a17e941036d26a808d928496d47c0f1016d6eea

我们可以看到,对于远程表的执行计划,如果关联条件是远程表的第一个字段,第一个字段上的索引是被忽略的,执行计划是选择全表扫描的。

测试场景2:

23312f6815c244640c69a88b5158c2cca91ef6d9

我们可以看到,对于远程表的执行计划,如果关联条件是远程表的第20个字段,这第20个字段上的索引是没有被忽略的,执行计划是走索引。

测试场景3:

3007fc600291a707809a426badfeee37472acce5

我们可以看到,对于远程表的执行计划,如果关联条件是远程表的第2个字段,这第2个字段上的索引是没有被忽略的,执行计划是走索引。

测试场景4:

248c37bb98d5c15fce3e230fe252751e1326627a

我们可以看到,对于远程表的执行计划,如果关联条件是远程表的第20个字段,这第20个字段上的索引是没有被忽略的,执行计划是走索引。

我们目前可以总结到,当远程表第21个索引建立的时候,通过dblink关联本地表和远程表,如果关联条件是远程表的第1个建立的索引的字段,那么这个索引将被忽略,从而走全表扫描。如果关联条件是远程表的第2个建立索引的字段,则不受影响。
似乎是有效索引的窗口是20个,当新建第21个,那么第1个就被无视了。

建立第22个索引,验证上述猜测

57ab359b49f5f1642f79533c010374e25f62dbf0

再次重复上面4个测试

测试场景1:

a92cf76772de5dce327c672d2a0d1af8ada95576

测试场景2:

faf036c3cd3f00641b332788209e52fcf346f17a

测试场景3:

ccd11a222ad333280bc87aa7500525ac75a8f859

上述的测试,其实是可以验证我们的猜测的。oracle对于通过dblink关联访问远程表,只是会意识到最近创建的20个索引的字段。这个意识到索引的窗口是20个,一旦建立了一个新索引,那么最旧的一个索引会被无视。

尝试rebuild索引


rebuild第2个索引

826621905b39e4ca86ff2d0a2cf9add2af8d6f09

重复上面测试

2ffadeb03009683605acfc884e8092a384e62c9f

所以我们看到,索引rebuild,是不能起到重新“唤醒”索引的作用。

尝试 drop and recreate 第2个索引

5f7a0e8eab2d7d72e249d1843e8262ed16bd2bd7

重复上面的测试3和测试4

8f5e6c5e51415f8baae6f5cacff596f83f78c3b3

我们可以看到,通过drop之后再重建,是可以“唤醒”第二个索引的。这也证明了我们20个索引识别的移动窗口,是按照索引的创建时间来移动的。

综上:

  1. 对于通过dblink关联本地表和远程表,如果远程表的索引个数少于20个,那么不受影响。
  2.  对于通过dblink关联本地表和远程表,如果远程表的索引个数增加到21个或以上,那么oracle在执行远程操作的时候,将忽略最早创建的那个索引,但是会以20个为窗口移动,最新建立的索引会被意识到。此时如果查询的关联条件中,使用到最早创建的那个索引的字段,由于忽略了索引,会走全表扫描。
  3. 要“唤醒”对原来索引的意识,rebuild索引无效,需要drop & create索引。
  4. 在本地表数据量比较少,远程表的数据量很大,而索引数量超过20个,且关联条件的字段时最早索引的情况下,可以考虑使用DRIVING_SITE的hint,将本地表的数据全量到远程中,此时远程的关联查询可以意识到那个索引。可见文末的例子。是否使用hint,需要评估本地表数据全量推送到远程的成本,和远程表使用全表扫的成本。

附:在22个索引的情况下,尝试采用DRIVING_SITE的hint:



a85bb15d9479d1a343cccda96449d74ca5bdd4b2

原文发布时间为:2017-10-26

本文作者:何剑敏

本文来自云栖社区合作伙伴“数据和云”,了解相关信息可以关注“数据和云”微信公众号

相关文章
|
24天前
|
存储 关系型数据库 MySQL
索引大战:探秘InnoDB数据库中B树和Hash索引的优劣
索引大战:探秘InnoDB数据库中B树和Hash索引的优劣
17 0
|
26天前
|
数据库 索引
数据库索引的作用和优点缺点
数据库索引的作用和优点缺点
15 1
|
2月前
|
存储 搜索推荐 关系型数据库
深度探讨数据库索引的数据结构及优化策略
深度探讨数据库索引的数据结构及优化策略
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
108 1
|
2月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
197 0
|
24天前
|
SQL 数据库 数据库管理
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
56 11
|
5天前
|
存储 机器学习/深度学习 搜索推荐
深入解析矢量数据库的数据模型与索引机制
【4月更文挑战第30天】本文深入探讨了矢量数据库的数据模型和索引机制。向量数据库以高维向量表示数据,采用稀疏或密集向量形式,并通过数据编码和组织优化存储与检索。索引机制包括基于树的(如KD-Tree和Ball Tree)、基于哈希的(LSH)和近似方法(PQ),加速相似性搜索。理解这些原理有助于利用矢量数据库处理大规模高维数据,应用于推荐系统、图像搜索等领域。随着技术发展,矢量数据库将扮演更重要角色。
|
6天前
|
关系型数据库 数据库 索引
关系型数据库使用索引
关系型数据库使用索引
18 1
|
7天前
|
关系型数据库 大数据 数据库
关系型数据库索引优化
关系型数据库索引优化是一个综合的过程,需要综合考虑数据的特点、查询的需求以及系统的性能要求。通过合理的索引策略和技术,可以显著提高数据库的查询性能和整体效率。
15 4
|
8天前
|
数据库 UED 索引
构建高效的数据库索引:提升查询性能的关键技巧
本文将深入探讨数据库索引的设计和优化,介绍如何构建高效的数据库索引以提升查询性能。通过学习本文,读者将掌握数据库索引的原理、常见类型以及优化策略,从而在实际应用中提升数据库查询效率。