问题描述
嗨,汤姆,
如果索引组织的表上的主键不是增量的,这是否会在OLTP负载下随着数据量的增长而产生瓶颈?
正在插入的数据难道不需要排序并插入叶子的中间吗?
这难道不会导致引擎不得不对磁盘上的页面进行排序,这将非常耗时和资源?
这是否也会阻碍页面锁定操作期间的读取加载 (读取/写入并发)?
这是一个假设。
我们正在做一些研究来做出决定,但我们发现的答案并不清楚。
您的帮助将不胜感激,因为这个决定对我们的设计至关重要。
如果索引组织的表上的主键不是增量的,这是否会在OLTP负载下随着数据量的增长而产生瓶颈?
正在插入的数据难道不需要排序并插入叶子的中间吗?
这难道不会导致引擎不得不对磁盘上的页面进行排序,这将非常耗时和资源?
这是否也会阻碍页面锁定操作期间的读取加载 (读取/写入并发)?
这是一个假设。
我们正在做一些研究来做出决定,但我们发现的答案并不清楚。
您的帮助将不胜感激,因为这个决定对我们的设计至关重要。
专家解答
If the primary key on a index-organized table is not incremental, wouldn't this create bottlenecks as data volume grows under OLTP loads?
如果有的话,增量列上的索引会带来更大的瓶颈。
请记住,(B树) 索引是有序的数据结构。因此,如果您插入的值总是在增加,这些都必须在索引的右侧边缘。
如果ID的当前最大值 = 999,并且您有三个会话插入以下值:
第1场会议: 1000
第2场会议: 1001
第3场会议: 1002
他们都需要访问ID上索引的最右边块来添加他们的条目。一次只有一个进程可以做到这一点。所以这给你一个索引 “热点”,减少写并发。
而如果会话插入这些值:
会议1:1
第2场会议: 500
第3场会议: 1000
很可能它们都将插入索引的不同块中。所以你可以有更大的写吞吐量。
Wouldn't the data being inserted needed to be sorted and inserted in the middle of the leaves?
是的,数据库需要在适当的叶块中插入新条目。这很可能是 “中间的”。
Wouldn't this cause the engine to have to order the pages on the disk, which would be very time and resource consuming?
不。索引是逻辑有序的数据结构。每个叶子块都有一个指向上一个和下一个叶子的指针。
但是连续的叶子可能在磁盘上的 “任何地方”。它们不必彼此相邻地物理存储。
如果在索引的 “中间” 插入新条目,Oracle数据库将找到相应的叶块。如果块中有空间,它会添加条目,您就完成了。
如果该块已满,它将进行50/50块分割。它创建了一个新的叶块,并将一半的条目放在那里。就这样。没有其他条目受到影响。没有其他数据移动发生。
这是relatively贵。但是,许多会话不太可能同时尝试访问这些块。所以你仍然有可能获得更大的写并发比增加值的索引。
Wouldn't this also impede read loads during page locking operations (reads / writes concurrency)?
我不知道你在这里得到什么。但是在Oracle数据库中,读者和作者永远不会互相阻止。
您似乎在混淆关于索引的一般理论,它们在其他数据库中的工作方式以及它们可能如何影响您的应用程序。
不要猜测,请阅读有关索引和索引组织表的Oracle数据库概念指南,以了解它们的工作原理:
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/cncpt/indexes-and-index-organized-tables.html#GUID-797E49E6-2DCE-4FD4-8E4A-6E761F1383D1
理查德·富特 (Richard Foote) 的 “Oracle B-Tree Index Internals: 重建真相” 还包含了许多与您的问题相关的细节,涵盖了块分割等:
https://richardfoote.files.wordpress.com/2007/12/index-internals-rebuilding-the-truth.pdf
最后,测试你提出的设计!理想地比较两个 (或更多) 设计。
测试后,检查它们是否满足您的性能需求。如果是,请停止担心所有这些,并继续构建您的应用程序;)
如果没有,请返回您的发现,我们将为您提供帮助。
如果有的话,增量列上的索引会带来更大的瓶颈。
请记住,(B树) 索引是有序的数据结构。因此,如果您插入的值总是在增加,这些都必须在索引的右侧边缘。
如果ID的当前最大值 = 999,并且您有三个会话插入以下值:
第1场会议: 1000
第2场会议: 1001
第3场会议: 1002
他们都需要访问ID上索引的最右边块来添加他们的条目。一次只有一个进程可以做到这一点。所以这给你一个索引 “热点”,减少写并发。
而如果会话插入这些值:
会议1:1
第2场会议: 500
第3场会议: 1000
很可能它们都将插入索引的不同块中。所以你可以有更大的写吞吐量。
Wouldn't the data being inserted needed to be sorted and inserted in the middle of the leaves?
是的,数据库需要在适当的叶块中插入新条目。这很可能是 “中间的”。
Wouldn't this cause the engine to have to order the pages on the disk, which would be very time and resource consuming?
不。索引是逻辑有序的数据结构。每个叶子块都有一个指向上一个和下一个叶子的指针。
但是连续的叶子可能在磁盘上的 “任何地方”。它们不必彼此相邻地物理存储。
如果在索引的 “中间” 插入新条目,Oracle数据库将找到相应的叶块。如果块中有空间,它会添加条目,您就完成了。
如果该块已满,它将进行50/50块分割。它创建了一个新的叶块,并将一半的条目放在那里。就这样。没有其他条目受到影响。没有其他数据移动发生。
这是relatively贵。但是,许多会话不太可能同时尝试访问这些块。所以你仍然有可能获得更大的写并发比增加值的索引。
Wouldn't this also impede read loads during page locking operations (reads / writes concurrency)?
我不知道你在这里得到什么。但是在Oracle数据库中,读者和作者永远不会互相阻止。
您似乎在混淆关于索引的一般理论,它们在其他数据库中的工作方式以及它们可能如何影响您的应用程序。
不要猜测,请阅读有关索引和索引组织表的Oracle数据库概念指南,以了解它们的工作原理:
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/cncpt/indexes-and-index-organized-tables.html#GUID-797E49E6-2DCE-4FD4-8E4A-6E761F1383D1
理查德·富特 (Richard Foote) 的 “Oracle B-Tree Index Internals: 重建真相” 还包含了许多与您的问题相关的细节,涵盖了块分割等:
https://richardfoote.files.wordpress.com/2007/12/index-internals-rebuilding-the-truth.pdf
最后,测试你提出的设计!理想地比较两个 (或更多) 设计。
测试后,检查它们是否满足您的性能需求。如果是,请停止担心所有这些,并继续构建您的应用程序;)
如果没有,请返回您的发现,我们将为您提供帮助。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




