我们在表中有大约10K行。我们希望有一个表单,其中我们有一个select下拉列表,其中包含此表中给定列的不同值。我们在相关列上有一个索引。
为了提高性能,我创建了一个包含不同值的缓存表,因此我们不需要针对10K行执行select distinct field from table
。令人惊讶的是,似乎做select * from cachetable
(10行)并不比对10K行做出选择明显更快。为什么是这样?索引是否完成所有工作?通过查询缓存表,主表中的行数会有多少性能提升?
答案 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_buffers
和hash_area_size
,所有操作都在内存中执行,您不会注意到任何差异。
但是,如果查询将用作更复杂查询的一部分,或者将被其他数据换出,则可能需要disk I/O
来访问数据,这会降低查询速度。
在几个会话的循环中运行您的查询(与用户连接的会话数量一样多),并查看它在这种情况下的执行情况。
答案 6 :(得分:0)
对于未来的计划和可伸缩性,您可能希望研究使用纯内存或比TCP DB往返更快的索引服务。很多人(包括我自己)使用Lucene通过将数据规范化为平面文件来实现这一目标。
Lucene有一个内置的Ram Drive目录索引器,可以在内存中构建索引 - 消除对文件系统的依赖,并大大提高速度。
最近,我构建了具有由Web服务包装的单个Ram驱动器索引的系统。然后,我将类似Ajax的下拉列表查询到Web服务以获得高可用性和高速度 - 没有数据库层,没有文件系统,只有纯内存和远程tcp数据包速度。
答案 7 :(得分:-1)
如果列上有索引,则所有值都在索引中,dbms永远不必查看表。它只是在索引中查找只有10个条目。如果这主要是只读数据,则将其缓存在内存中。缓存通过减轻工作数据库来帮助实现可扩展性。如果一个30个查询同时进行,那么对没有用户的数据库进行快速查询可能会表现不佳。