有一个应用,需要经常做类似这样的查询 select * from SomeTable where key in (KeySet) ,其中 KeySet 可能很大,比如包含几百甚至几千个元素。理想中的情况,数据库应该先在 BTree 中查找到 KeySet 中的 Key 所在的物理页面地址,然后再对这物理地址排序,最后按顺序读入这些页面内容并填充结果。如果这样做,那么在最坏情况下,KeySet 中元素的逻辑排序完全不等于其物理顺序,并且,每个Key所在的页面还不在相同的磁盘柱面上,这样,查询集合中所有 key 所花的磁盘时间就等于 Key 的数目乘以磁盘的“平均潜伏时间”(Average Latency)再加上“柱面切换时间”(Cylinder Switch Time) 和 传输时间(Transfer Time):
T = KeySet.size * (al + cst + tt)
其中 al = Average Latency, cst = Cylinder Switch Time,实际上我这里说的 cst 比Cylinder Switch Time要大一些,因为柱面不一定相邻,中间可能像个几十个甚至上百的柱面,但这个时间跟cst应该比较接近。
这里假定内部处理所花的时间基本上可以忽略,在一般情况下也的确如此。一般情况下一个物理页面很小,如8K到16K。
对于高速的每分钟15000转的服务器硬盘,Average Seek Time 是8ms,连续传输速度是 200M,al=2ms,cst=1ms,使用16K的页面尺寸,则 tt = 0.025ms,因此可以先忽略tt。
如果KeySet中有4000个元素,并且BTree的所有内部节点(索引结点)都已经缓存,那么一次这样的查询需要 4000*(2ms + 1ms) = 12 秒!
而如果每查找一个key都启动一次在整个 BTree 上的查找,也假定BTree的所有内部节点(索引结点)都已经缓存,那么这个时间就是:4000*(al+ast) = 4000 * 10ms = 40秒
虽然经过优化,这个优化版的时间仍然很长,但是,这是查询4000个Key的最坏情况,很可能这些Key有一些局部性,比如他们只位于200个不同的柱面上(平均每个柱面20个key),这是非常可能的。这样,这个时间就缩短到了0.6秒,如果我们把数据库进行集群,比如10个服务器结点,那么这个数据可以缩短到0.06秒,这个时间就基本上可以接受了。对于传统方法,在这种情况下是0.2秒。
我在一个项目中碰到这样的瓶颈(数据量大约2T,使用磁盘阵列),找不到支持这种优化的系统。使用BDB(BerkeleyDB),最多也只能减少数据拷贝和网络传输的时间,这样的一个查询经常需要40秒以上的时间。让我难以忍受,因为事先根据我的分析和计算,Key是有一定局部性的,这个时间应该在2秒以内,再不行也应该在5秒内。最后我自己写了一个只读的BTree索引系统(完整的BTree处理太复杂),使用了这种优化,查询时间一下子缩短到了1秒以内,最后使用了10个分开的阵列,时间缩短到了0.1秒,基本可以满足需求。这个效果比我预先估计的要快很多,因为基于BerkeleyDB的效果,我猜想可能也就比BerkeleyDB快4倍的时间。
不过这个结果也证实了我之前的猜想:数据有一定的局部性,虽然KeySet中有4000个Key,但是这些Key中有很多是相邻的。并且,BerkeleyDB的实现可能也没有我想象的好,也有可能是其它原因,比如可能每次查询的间隔时间较大,使得即使数据相邻,也需要重新调度磁头等等。
如果随着技术的发展,磁盘最终被其它介质(如Flash)代替,这种方法是不是就没了用武之地?
分享到:
相关推荐
同时,理解查询执行计划有助于识别性能瓶颈,优化查询语句。 6. **减少数据冗余**: 数据冗余可能导致一致性问题,增加存储开销,并可能在更新时引发更多的冲突。遵循第一范式(1NF)和第三范式(3NF)的设计原则...
"浅析分布式数据库查询优化" 分布式数据库查询优化是分布式数据库系统中的一个关键技术,旨在提高分布式数据库查询的性能和效率。分布式数据库系统是一个物理上分散而逻辑上集中的数据库系统,使用计算机网络将地理...
分布式数据库是物理上分散在不同节点上,逻辑上是统一管理的数据库集合。它能够提高数据的可用性、可靠性,并具有较好的扩展性。 2. 分布式数据库的架构与模型:分布式数据库可能采用不同的架构,如客户端-服务器...
本教程集合将深入探讨SQLite数据库的相关知识,包括基本概念、SQL语言、数据库操作以及优化策略。 一、SQLite数据库基础 SQLite数据库的核心特点是其小巧且易于使用。它支持ACID(原子性、一致性、隔离性、持久性)...
性能优化主要包括查询优化、索引优化、存储优化等。查询优化通过选择最优执行计划来提高查询速度;索引可以加速数据查找,但也会占用存储空间;存储优化则关注数据的存储方式和存储设备的选择。 这个"数据库概论...
在开发过程中,优化查询计划是提高数据库效率的一个关键步骤。优化计划是优化器对用户提交的SQL语句进行优化后产生的语句集合。尽管数据库产品已经具备优化能力,但最终的SQL语句和索引体系仍然是系统优化的基础。一...
SQL Server作为主流的关系型数据库管理系统之一,其调优策略包括对查询性能、存储过程、索引以及服务器资源的合理分配等进行优化。通过分析SQL Server的执行计划,识别慢查询,并对其进行优化,如调整查询语句结构或...
"SQL Server数据库性能优化" SQL Server数据库性能的优化是数据库应用系统开发中的一个重要...合理的数据库设计、慎用游标、索引的使用、查询优化、数据库碎片整理、数据库备份和恢复等都是数据库性能优化的重要手段。
3. 索引:索引是提高查询速度的关键,包括B树索引、哈希索引等,合理使用索引能有效优化查询性能。 4. 视图:视图是虚拟表,基于一个或多个表的查询结果,可以简化复杂的查询并提供数据安全。 5. 存储过程:存储...
本资源包是一个全面的数据库学习集合,包括入门资料、错误码参考以及各种数据库的教材,旨在帮助初学者和经验丰富的开发者深入理解数据库系统。 首先,让我们关注SQL(Structured Query Language),这是用于管理和...
分布式数据库的第五章主要探讨了分布查询的存取优化,这是在分布式数据库系统中至关重要的一个环节。在这样的系统中,数据分布在多个节点上,因此查询优化的目标是找到执行查询的最低成本方案,同时考虑I/O成本、CPU...
SDD-1算法的优点在于它考虑了多种因素(如程序费用、效率和收益)来优化查询过程,但同时它也存在一些局限性,比如对某些半连接程序代价过高时的处理。因此,算法的后优化步骤显得尤为重要,能够通过调整策略来适应...
执行计划是优化查询性能的核心。在Oracle中,执行计划显示了SQL语句执行的具体步骤,包括如何访问数据,如全盘扫描和ROWID扫描。全盘扫描会读取表的所有行,而ROWID扫描则通过行的唯一标识符定位数据。此外,B树索引...
通过维护一个预创建的数据库连接集合,当应用程序需要访问数据库时,可以从连接池中获取空闲连接,而无需每次重新建立连接,这极大地减少了连接建立和断开的时间,提升了整体性能。 #### 三、操作策略优化 ##### 1...
《空间数据库查询处理与优化详解》 空间数据库的查询处理与优化是数据库管理中的关键环节,尤其在地理信息系统(GIS)等领域中尤为重要。本篇将深入探讨这一主题,包括空间操作、查询优化策略以及空间索引结构分析...
另外,对于联接的列,如果联接值为静态值,优化器通常不会使用索引,这也是优化查询时需要注意的一个点。 避免使用相关子查询也是提高SQL查询效率的重要方面。相关子查询会降低查询效率,因为它需要在处理外层查询...
由于SQL语句是数据库操作的主要载体,优化查询语句能够显著提高系统效率,尤其是在处理大量数据和复杂查询的业务场景下。 【查询优化的必要性】 在Oracle数据库中,很多性能问题源于数据库设计不合理。SQL语句是与...
在实际应用中,我们还需要关注查询性能,比如使用预编译的SQL(PreparedStatement)、优化查询语句、合理设置数据库索引等。同时,通过监控线程池状态和系统资源使用情况,可以对线程池参数进行调整,以达到最佳性能...