DB索引速度与缓存

时间:2009-03-26 19:49:26

标签: performance oracle caching indexing

我们在表中有大约10K行。我们希望有一个表单,其中我们有一个select下拉列表,其中包含此表中给定列的不同值。我们在相关列上有一个索引。

为了提高性能,我创建了一个包含不同值的缓存表,因此我们不需要针对10K行执行select distinct field from table。令人惊讶的是,似乎做select * from cachetable(10行)并不比对10K行做出选择明显更快。为什么是这样?索引是否完成所有工作?通过查询缓存表,主表中的行数会有多少性能提升?

8 个答案:

答案 0 :(得分:5)

对于数据库,10K行 nothing 。你没有看到太大的区别,因为实际的计算时间是最小的,其中大部分是由其他恒定的开销消耗的。

很难预测何时开始注意到差异,但可能会有大约一百万行。

如果您已经设置了缓存并且没有任何不利影响,那么您也可以将其保留。

答案 1 :(得分:4)

10k行并不多...当你达到500k~100万行时开始关怀。

索引做得很好,特别是如果你只有10个不同的索引值。

答案 2 :(得分:3)

这取决于许多因素 - 您的数据库具有的内存量,表中行的大小,参数化查询的使用等等,但通常10K不是很多行,特别是如果表是很好地索引,它不会导致任何现代RDBMS出任何汗水。

根据经验,我通常只会在通过100K行标记时开始密切关注表上的性能问题,如果正确索引并且通过这样的方式访问,500K通常不会导致很多问题。在大型桌子上,性能通常会出现灾难性的下降 - 你可能在500K行上可以正常但在600K上爬行 - 但是在你可能遇到这些问题之前还有很长的路要走。

答案 3 :(得分:3)

  

索引是否完成所有工作?

您可以通过查看执行计划来了解查询的执行方式。

例如,试试这个:

explain plan for select distinct field from table;

select * from table(dbms_xplan.display);

我注意到你没有包含ORDER BY。如果不包含ORDER BY,那么结果集的顺序可能是随机的,特别是如果oracle使用HASH算法制作不同的列表。你应该检查一下。

因此,我将查看您认为使用索引的原始查询的执行计划,以及基于缓存表的原始查询的执行计划。也许张贴他们,我们可以评论真实情况。

事实上,缓存表通常被实现为物化视图,特别是如果主表通常非常静态。

答案 4 :(得分:2)

严重的过早优化。让数据库完成它的工作,可能会对配置进行一些调整(特别是如果是MySQL,它有几种缓存类型和设置)。

答案 5 :(得分:1)

10K行中的查询最有可能使用HASH SORT UNIQUE

由于10K最有可能适合db_buffershash_area_size,所有操作都在内存中执行,您不会注意到任何差异。

但是,如果查询将用作更复杂查询的一部分,或者将被其他数据换出,则可能需要disk I/O来访问数据,这会降低查询速度。

在几个会话的循环中运行您的查询(与用户连接的会话数量一样多),并查看它在这种情况下的执行情况。

答案 6 :(得分:0)

对于未来的计划和可伸缩性,您可能希望研究使用纯内存或比TCP DB往返更快的索引服务。很多人(包括我自己)使用Lucene通过将数据规范化为平面文件来实现这一目标。

Lucene有一个内置的Ram Drive目录索引器,可以在内存中构建索引 - 消除对文件系统的依赖,并大大提高速度。

最近,我构建了具有由Web服务包装的单个Ram驱动器索引的系统。然后,我将类似Ajax的下拉列表查询到Web服务以获得高可用性和高速度 - 没有数据库层,没有文件系统,只有纯内存和远程tcp数据包速度。

答案 7 :(得分:-1)

如果列上有索引,则所有值都在索引中,dbms永远不必查看表。它只是在索引中查找只有10个条目。如果这主要是只读数据,则将其缓存在内存中。缓存通过减轻工作数据库来帮助实现可扩展性。如果一个30个查询同时进行,那么对没有用户的数据库进行快速查询可能会表现不佳。