Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL中的快速查询_Sql_Postgresql_Postgresql 9.6 - Fatal编程技术网

PostgreSQL中的快速查询

PostgreSQL中的快速查询,sql,postgresql,postgresql-9.6,Sql,Postgresql,Postgresql 9.6,我有一个非常大的数据库(~1TB),所以运行一个非常简单的查询可能需要很长时间。例如: EXPLAIN select count(*) from users; 获取磁盘页的成本为44661683.87。因此,执行成本非常高。 当我尝试对查询设置限制时,如: EXPLAIN select count(*) from users limit 10; 执行查询的成本保持不变,即44661683.87磁盘页获取 那么(1)是否可以对数据子集执行查询,然后外推到表的其余部分?可以使用以下方法快速找到

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

EXPLAIN select count(*) from users; 
获取磁盘页的成本为44661683.87。因此,执行成本非常高。 当我尝试对查询设置限制时,如:

EXPLAIN select count(*) from users limit 10;
执行查询的成本保持不变,即44661683.87磁盘页获取

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

SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = 'users';
此外,(2)是否可以选择随机分布的行子集?

选择计数(*)
是一个聚合查询,没有
分组依据
。它返回1行,因此限制没有影响

你似乎想要:

select count(*)
from (select u.*
      from users u
      limit 10
     );
至于你的第二个问题,Postgres在9.5版中引入了
tablesample

选择计数(*)
是一个聚合查询,没有
分组依据
。它返回1行,因此限制没有影响

你似乎想要:

select count(*)
from (select u.*
      from users u
      limit 10
     );
至于你的第二个问题,Postgres在9.5版中引入了
tablesample

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

您可以使用
tablesample
选项:

select count(*) * 10
from the_table tablesample system (10);
tablesample系统(10)
只扫描表中10%的块,这应该相当快。如果将结果行数乘以10,则总行数的近似值为(!)。样本量越小,速度越快,这将是-但也不太准确

I数字的准确性取决于您的表有多少可用空间,因为10%(或您选择的任何样本大小)基于表中的块总数。如果有许多空闲(或半空闲)块,那么这个数字就不太可靠

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

您可以使用
tablesample
选项:

select count(*) * 10
from the_table tablesample system (10);
tablesample系统(10)
只扫描表中10%的块,这应该相当快。如果将结果行数乘以10,则总行数的近似值为(!)。样本量越小,速度越快,这将是-但也不太准确


I数字的准确性取决于您的表有多少可用空间,因为10%(或您选择的任何样本大小)基于表中的块总数。如果有许多空闲(或半空闲)块,那么这个数字就不太可靠

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

EXPLAIN SELECT COUNT(*) FROM (SELECT DISTINCT id FROM users) u;

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

EXPLAIN SELECT COUNT(*) FROM (SELECT DISTINCT id FROM users) u;

这不会改变任何事情。Postgres将扫描PK索引以查找
计数(*)
您确定吗?我刚刚在第9.6页的一个非常大的表上运行了SELECT COUNT(*)的EXPLAIN,它在表上显示了Seq Scan,而不是索引。仅索引扫描受最新统计数据和正确清空的表的约束-但我确实看到了几乎所有表的这一点。类似这样的事情:这不会改变任何事情。Postgres将扫描PK索引以查找
计数(*)
您确定吗?我刚刚在第9.6页的一个非常大的表上运行了SELECT COUNT(*)的EXPLAIN,它在表上显示了Seq Scan,而不是索引。仅索引扫描受最新统计数据和正确清空的表的约束-但我确实看到了几乎所有表的这一点。大概是这样的: