我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。
为什么你的数据库有时不用索引?一个关键参数告诉你答案
想象一下,你要在图书馆找10本相关的书。如果这些书都放在同一个书架上,你只需要去一次书架就能全部找到。但如果这些书分散在整个图书馆的不同区域,你就需要来回跑很多次,花费更多时间和精力。
数据库中的"聚类因子"(Clustering Factor)就是衡量数据排列有序程度的指标,它决定了数据库通过索引查找数据的效率。
什么是聚类因子?
聚类因子是Oracle数据库中的一个重要参数,它告诉我们表中的数据是否按照索引的顺序来存储:
- 聚类因子接近数据块数量 = 数据排列有序(好比书籍都放在同一个书架上)
- 聚类因子接近数据行数量 = 数据排列混乱(好比书籍分散在整个图书馆)
实际例子说明问题
通过一个实际测试,我们创建了两个完全相同的表(都有10万行数据),但数据的排列方式不同:
- 有序表(COLOCATED):聚类因子为1190(接近数据块数量1252)
- 无序表(DISORGANIZED):聚类因子为99929(接近数据行数量10万)
当查询表中10%的数据时,出现了截然不同的结果:
- 有序表:数据库选择使用索引(成本142)
- 无序表:数据库选择全表扫描(成本333)
为什么会这样?
因为数据库在通过索引查找数据时,如果发现下一行数据就在同一个数据块中,它不需要额外的I/O操作。就像在图书馆找书,如果下一本书就在当前书架上,你不需要走到其他区域。
但对于无序表,几乎每一行数据都在不同的数据块中,数据库需要频繁进行I/O操作,效率反而比直接全表扫描还要低。
给开发者的启示
-
索引不是万能的:即使建立了索引,数据库也不一定会使用,数据物理存储方式直接影响查询效率
-
不要盲目重建表:试图让所有索引都有良好的聚类因子是不现实的,因为数据只能按一种方式物理排序
-
考虑其他方案:如果数据物理聚类很重要,可以考虑使用:
- 索引组织表(IOT)
- B*树簇
- 哈希簇
简单总结
聚类因子就像图书馆的书籍摆放系统:有序摆放让你快速找到所需书籍,混乱摆放则让你跑来跑去效率低下。了解这个概念,能帮助你更好地理解数据库的行为,做出更合理的设计决策。
记住:有时候全表扫描比使用索引更高效,这不是优化器的错误,而是它基于数据实际情况做出的明智选择。
------------------作者介绍-----------------------
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)