PostgreSQL中的快速查询

时间:2018-02-22 15:50:04

标签: sql postgresql postgresql-9.6

我有一个非常大的数据库(~1TB),所以运行一个非常简单的查询可能需要很长时间。例如。 for:

nlm

成本是44661683.87磁盘页面获取。因此,执行起来非常昂贵。 当我尝试对查询设置限制时:

EXPLAIN select count(*) from users; 

执行查询的成本保持不变,即44661683.87磁盘页面获取。

那么(1)是否可以对数据子集执行查询,然后推断到表的其余部分?可以使用以下内容快速找到行大小:

EXPLAIN select count(*) from users limit 10;

此外,(2)是否可以选择随机分布的行子集?

3 个答案:

答案 0 :(得分:1)

group by是一个没有select count(*) from (select u.* from users u limit 10 ); 的聚合查询。它返回1行,因此限制没有影响。

你似乎想要:

tablesample

至于你的第二个问题,Postgres在9.5版中引入了clc; clear all ; M = 20 ; N = 100 ; R1 = 1 ; % yttre radien nR = linspace(0,R1,M) ; nT = linspace(0,2*pi,N) ; nx = linspace(-0.1,0.9,N); ny = linspace(-1,1,M); %nT = pi/180*(0:NT:theta) ; [B, Z] = meshgrid(nx,ny); [R, T] = meshgrid(nR,nT) ; lambda = 1; fun= @(s) e^((i*2*pi/lambda)*(1/2 * (cos(lambda/(4*pi*s))/2))); % Convert grid to cartesian coordintes X = R.*cos(T); Y = R.*sin(T); [m,n]=size(X); % Plot grid figure set(gcf,'color','w') ; axis equal axis off box on hold on for i=1:m plot(X(i,:),Y(i,:),'k','linewidth',1.5); end for j=1:n plot(X(:,j),Y(:,j),'k','linewidth',1.5); plot(B(:,j),Z(:,j),'b','linewidth',1.5); end You can investigate that.

答案 1 :(得分:1)

  

是否可以对数据子集执行查询,然后推断到表的其余部分

您可以使用DELETE FROM backup WHERE id IN ( SELECT ID FROM ( SELECT id FROM backup WHERE id > 0 AND userId NOT IN (SELECT id FROM user WHERE state > 0) ORDER BY id ASC LIMIT 100 ) a ); 选项:

tablesample

select count(*) * 10 from the_table tablesample system (10); 只能扫描表中10%的块,这些块应该非常快。如果将得到的行数乘以10,则会得到总行数的近似值(!)。样本量越小越快,这将是 - 但也不太准确。

我的数字的准确性取决于您的表有多少可用空间,因为10%(或您选择的任何样本大小)基于表中的块总数。如果有许多免费(或半免费)块,则该数字将不太可靠。

答案 2 :(得分:1)

如果在users表(或另一列上的索引)上有主键索引,则可以使用该索引进行仅索引扫描,这样可以产生更好的执行计划。但是,奇怪的是,它不适用于COUNT,因此您可以在子查询中执行SELECT DISTINCT,然后在外部查询上执行COUNT以强制它使用索引:

dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, ^{
        <#code#>
    })