让我说我查询一个500K行的表。我想开始查看获取缓冲区中的任何行,该缓冲区保存结果集,即使查询尚未完成。我想通过获取缓冲区滚动。如果我向前滚动太远,我想显示一条消息,如:“在最后的行程中找到了BUFFER ......查询还没有完成”。
除了FIRST ROWS提示指令之外,可以在Oracle,Informix,MySQL或其他RDBMS中提供这样的功能吗?
整个想法是能够在长查询完成之前开始查看行,同时显示可以立即查看的行数的计数器。
编辑:我建议的可能需要对数据库服务器架构进行根本性改变,以及它们处理内部提取缓冲区的方式,例如:锁定结果集直到查询完成等。像我建议的那样的功能将非常有用,特别是对于需要很长时间才能完成的查询。为什么要等到整个查询完成,当您可以在查询继续收集更多结果时开始查看某些结果时!
答案 0 :(得分:5)
答案 1 :(得分:2)
可以使用分析函数完成,但是如果没有索引,Oracle必须完全扫描表以确定计数。分析可以简化您的查询:
SELECT x,y,z, count(*) over () the_count
FROM your_table
WHERE ...
返回的每一行都将包含查询在_count中返回的总行数。但是,正如我所说,Oracle必须完成查询以确定返回任何内容之前的计数。
根据您处理查询的方式(例如,表单中的PL / SQL块),您可以使用上述查询打开游标,然后遍历游标并显示记录集并为用户提供有机会取消。
答案 2 :(得分:2)
有三个基本限制因素:
查询的执行计划。如果执行计划在最后有一个阻塞操作(例如排序或急切的假脱机),则引擎无法在查询执行的早期返回行。它必须等到所有行都完全处理完毕,然后才能尽快将数据返回给客户端。这个时间本身可能很明显,所以这部分可能适用于你所谈论的内容。但是,一般情况下,您无法保证查询很快就会有很多可用的内容。
数据库连接库。从数据库返回记录集时,驱动程序可以使用服务器端分页或客户端分页。使用哪个可以并且确实会影响将返回哪些行以及何时返回。客户端分页会强制立即返回整个查询,从而减少在数据全部显示之前显示任何数据的机会。仔细使用正确的分页方法对于在查询生命周期的早期显示数据至关重要。
客户端程序使用同步或异步方法。如果您只是复制并粘贴一些用于执行查询的Web示例代码,那么在查询仍在运行时,您将不太可能使用早期结果 - 而是该方法将阻止,并且在它全部进入之前您将得不到任何结果当然,服务器端分页(参见第2点)可以缓解这种情况,但是如果你没有专门使用异步方法,你的应用程序将至少在短时间内被阻止。对于正在阅读此使用.Net的人,您可能需要查看Asynchronous Operations in .Net Framework。
如果你把所有这些都搞定了,并且使用了FAST FIRSTROW技术,你可以能够做你正在寻找的一些东西。但是没有保证。
答案 3 :(得分:1)
我不确定如何完成此操作,因为查询必须在结果知晓之前完成。没有RDBMS(我知道)提供了任何方法来确定在查询完成之前找到了多少查询结果。
我无法说实话,因为我从未见过源代码这样的功能在Oracle中有多昂贵。但是,从外部来看,我认为这将是相当昂贵的,并且可以加倍(如果不是更多)查询完成的时间长度。这意味着在每次结果之后更新一个原子计数器,当你说出数百万个可能的行时这并不便宜。
答案 4 :(得分:1)
所以我在这个答案中提出我的意见 - 就Oracle而言。
Oracle在每个实例的系统全局区域(SGA)内维护自己的缓冲区缓存。缓冲区缓存的命中率取决于大小调整,大部分时间达到90%,这意味着在没有到达磁盘的情况下,将满足10个命中中的9个。
考虑到上述情况,即使存在“方式”(可以这么说)来访问运行的查询的缓冲区chache,结果也将高度依赖于缓存大小调整因子。如果缓冲区缓存太小,缓存命中率将会很小,并且会产生更多的物理磁盘I / O,这将使缓冲区缓存在临时数据内容方面不可靠。如果缓冲区缓存太大,那么部分缓冲区缓存将被利用不足,内存资源将被浪费,这将导致过多的不必要的处理尝试访问缓冲区缓存,以便查看它对于你想要的数据。
另外,根据您的缓存大小和SGA内存,ODBC驱动程序/优化器可以确定何时以及使用多少内容(缓存缓存或直接磁盘I / O)。
在尝试访问“缓冲区缓存”以找到您正在寻找的“行”方面,可能有一种方法(或在不久的将来)这样做,但是没有办法知道是什么你正在寻找(“行”)是否存在。
此外,对大型表的全表扫描通常会导致物理磁盘读取和较低的缓冲区缓存命中率。您可以通过查询v$filestat
并加入到数据文件级别来了解全表扫描活动。 SYS.dba_data_files
。以下是您可以使用的查询和示例结果:
SELECT A.file_name, B.phyrds, B.phyblkrd
FROM SYS.dba_data_files A, v$filestat B
WHERE B.file# = A.file_id
ORDER BY A.file_id;
由于整个考验严重依赖于多个参数和统计数据,因此您所寻找的结果可能仍然是由这些因素驱动的概率。