2011-03-01 138 views
0

任何人都可以请帮我理解PostgreSQL的内部?如果我从两个客户端访问两个单独的表(相同的数据库),那么与在不同时间在不同的表上执行查询时相比,查询响应时间会增加。我很困惑,不同表上的同时查询如何导致更长的执行时间。理论上,如果我在不同的表上同时执行查询,则两个客户端的表都被解锁,并且执行时间应该保持不变。PostgreSQL中单独表(同一数据库)上的并发查询

我想知道由于使用公共共享资源是否有任何开销,因为数据库是相同的。

请帮忙!

回答

1

那么,我们来看最基本的情况。

你有两个大的表存储在磁盘上。

你他们对这两个单独的表运行两个查询。

但是,虽然它们是由DB表示的两个单独的逻辑表,但它们实际上共享相同的磁盘。

因此,当每个单独的postgres进程读取每个表时,磁盘头都在滑行并来回跳动以尝试提供数据,因此每个进程都在磁盘驱动器上彼此对抗,单个共享资源。

这就像有一个银行有两个出纳窗口和两条线,但只有一个出纳员在后面做所有的工作。

这并没有考虑到其他几十亿因素,它们可能会降低或加快您的查询速度。只是一个可能发生的案例的基本例子。

+0

寻求你描述的磁盘在实践中并不真正发生。如果有较长的顺序读取,OS级预读将确保每个表的读取块将足够​​长,以便查找时间不重要。 – intgr 2011-03-19 16:21:30

0

这里有很多事情要记住。

首先,顺序和随机磁盘I/O之间存在巨大差异。使用随机磁盘I/O,您不会获得操作系统来帮助预取,但是您可以使用顺序访问。因此,在连续读取操作系统时,将获取比我们最初读取的数据更多的数据,我们将在操作系统从另一个表中提取另一个查询的数据时访问它。在随机访问中,您会得到所描述的效果,但是在随机访问中,您无论如何都需要等磁盘驱动器移动而没有并发问题,因为您正在进行随机读取。

要记住的第二件事是不同的查询计划有不同的I/O配置文件。如果我们将表的10%页面从磁盘中拉出来,并且我们有一个索引,那么我们可以选择顺序加载索引,然后按照逻辑顺序遍历来查找我们的记录(而磁盘正在做些什么对于其他查询),然后接受开销,从磁盘随机访问几个页面。这当然涉及到这种等待头部移动的问题,并且可能会或可能不会有并发问题,这可能会使情况变得更糟。因此,查询1完成索引扫描并且查询2将执行顺序扫描是完全可能的,并且将在查询1处理索引时提取所需的大部分数据。那么你可能会遇到一些Will描述的问题,但可能并不多。

最后的事情,这是非常关键的,是缓存。数据库倾向于缓存大量记录,因为这完全避免了磁盘I/O。所以在这种情况下,你可能实际上有一些非常不同的东西。查询1可能从内存或主要来自内存中工作,而查询2可能会碰到磁盘。一般情况下,如果你有足够的内存来满足你感兴趣的大部分数据的要求,那么这些数据就可以放在内存中,这样就可以为其他软件(如内核)腾出空间,那么可能出现的任何磁盘I/O问题都不会成为实际问题,并且唯一一次你通常会碰到磁盘将是提交WAL段。

所以答案是“这取决于”。这取决于你的系统。这取决于你的RAM和数据大小。这取决于你的硬盘和操作系统。这取决于具体的查询。这取决于其他使用模式。这取决于。