- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是什么让坏行估计成为 SQL 查询性能中的痛点?我很想知道其中的内部原因。
通常错误的行估计实际上会选择正确的计划,好查询和坏查询之间的唯一区别是估计的行数。
为什么经常会出现如此巨大的性能差异?
是因为Postgres使用行估计来分配内存吗?
最佳答案
Postgresql 优化器是一个基于成本的优化器(CBO),查询将从执行计划中以最小的成本执行,成本将通过表的统计来计算。
Why are bad row estimates slow in Postgres?
因为错误的统计可能会选择错误的执行计划。这是一个例子
有两个表,T1
有20000000行,T2
有1000000行。
CREATE TABLE T1 (
ID INT NOT NULL PRIMARY KEY,
val INT NOT NULL,
col1 UUID NOT NULL,
col2 UUID NOT NULL,
col3 UUID NOT NULL,
col4 UUID NOT NULL,
col5 UUID NOT NULL,
col6 UUID NOT NULL
);
INSERT INTO T1
SELECT i,
RANDOM() * 1000000,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid
FROM generate_series(1,20000000) i;
CREATE TABLE T2 (
ID INT NOT NULL PRIMARY KEY,
val INT NOT NULL,
col1 UUID NOT NULL,
col2 UUID NOT NULL,
col3 UUID NOT NULL,
col4 UUID NOT NULL,
col5 UUID NOT NULL,
col6 UUID NOT NULL
);
INSERT INTO T2
SELECT i,
RANDOM() * 1000000,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid,
md5(random()::text || clock_timestamp()::text)::uuid
FROM generate_series(1,1000000) i;
当我们对表进行join
时,我们将得到一个可能使用Merge JOIN
的执行计划
EXPLAIN (ANALYZE,TIMING ON,BUFFERS ON)
SELECT t1.*
FROM T1
INNER JOIN T2 ON t1.id = t2.id
WHERE t1.id < 1000000
"Gather (cost=1016.37..30569.85 rows=53968 width=104) (actual time=0.278..837.297 rows=999999 loops=1)"
" Workers Planned: 2"
" Workers Launched: 2"
" Buffers: shared hit=38273 read=21841"
" -> Merge Join (cost=16.37..24173.05 rows=22487 width=104) (actual time=11.993..662.770 rows=333333 loops=3)"
" Merge Cond: (t2.id = t1.id)"
" Buffers: shared hit=38273 read=21841"
" -> Parallel Index Only Scan using t2_pkey on t2 (cost=0.42..20147.09 rows=416667 width=4) (actual time=0.041..69.947 rows=333333 loops=3)"
" Heap Fetches: 0"
" Buffers: shared hit=6 read=2732"
" -> Index Scan using t1_pkey on t1 (cost=0.44..48427.24 rows=1079360 width=104) (actual time=0.041..329.874 rows=999819 loops=3)"
" Index Cond: (id < 1000000)"
" Buffers: shared hit=38267 read=19109"
"Planning:"
" Buffers: shared hit=4 read=8"
"Planning Time: 0.228 ms"
"Execution Time: 906.760 ms"
但是当我如下更新很多行时让 id 加上 100000000
当 id 小于 1000000
update T1
set id = id + 100000000
where id < 1000000
我们再次使用相同的查询,它将使用Merge JOIN
,但应该有另一个更好的选择而不是Merge JOIN
。
如果您没有达到 autovacuum_analyze_threshold(autovacuum_analyze_threshold
默认值为 0.1
这意味着我们需要创建超过 10%
死元组 postgresql会自动更新统计)
EXPLAIN (ANALYZE,TIMING ON,BUFFERS ON)
SELECT t1.*
FROM T1
INNER JOIN T2 ON t1.id = t2.id
WHERE t1.id < 1000000
"Gather (cost=1016.37..30707.83 rows=53968 width=104) (actual time=51.403..55.517 rows=0 loops=1)"
" Workers Planned: 2"
" Workers Launched: 2"
" Buffers: shared hit=8215"
" -> Merge Join (cost=16.37..24311.03 rows=22487 width=104) (actual time=6.736..6.738 rows=0 loops=3)"
" Merge Cond: (t2.id = t1.id)"
" Buffers: shared hit=8215"
" -> Parallel Index Only Scan using t2_pkey on t2 (cost=0.42..20147.09 rows=416667 width=4) (actual time=0.024..0.024 rows=1 loops=3)"
" Heap Fetches: 0"
" Buffers: shared hit=8"
" -> Index Scan using t1_pkey on t1 (cost=0.44..50848.71 rows=1133330 width=104) (actual time=6.710..6.710 rows=0 loops=3)"
" Index Cond: (id < 1000000)"
" Buffers: shared hit=8207"
"Planning:"
" Buffers: shared hit=2745"
"Planning Time: 3.938 ms"
"Execution Time: 55.550 ms"
当我们使用手动ANALYZE T1;
意味着更新T1
表统计信息,然后再次查询时,查询将得到Nested Loop
更好比 Merge JOIN
"QUERY PLAN"
"Nested Loop (cost=0.86..8.90 rows=1 width=104) (actual time=0.004..0.004 rows=0 loops=1)"
" Buffers: shared hit=3"
" -> Index Scan using t1_pkey on t1 (cost=0.44..4.46 rows=1 width=104) (actual time=0.003..0.003 rows=0 loops=1)"
" Index Cond: (id < 1000000)"
" Buffers: shared hit=3"
" -> Index Only Scan using t2_pkey on t2 (cost=0.42..4.44 rows=1 width=4) (never executed)"
" Index Cond: (id = t1.id)"
" Heap Fetches: 0"
"Planning:"
" Buffers: shared hit=20"
"Planning Time: 0.232 ms"
"Execution Time: 0.027 ms"
小结:
表中精确的统计信息将帮助优化器通过表中精确的COST得到正确的执行计划。
这是一个脚本,可以帮助我们最后一次搜索 last_analyze
& last_vacuum
。
SELECT
schemaname, relname,
last_vacuum, last_autovacuum,
vacuum_count, autovacuum_count,
last_analyze,last_autoanalyze
FROM pg_stat_user_tables
where relname = 'tablename';
关于postgresql - 为什么 Postgres 中的错误行估计很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71321936/
我想计算或至少估计放置在相机/kinect 前面的物体的体积。知道我应该从哪里开始吗?你推荐 OpenCV 吗?您是否推荐任何其他技术,例如声纳/激光? 最佳答案 一直在用 OpenCV 2.3 编写
我想知道 MySQL 对表中总行数的 TABLE_ROWS 估计值是否有限制或保证误差范围? 最佳答案 如果它与 SHOW TABLE STATUS 发出的数字类似,则至少会偏差 +/- 40%,有时
我们都曾 mock 过“还剩 X 分钟”的对话框,它似乎过于简单,但我们如何改进它呢? 实际上,输入是截至当前时间的一组下载速度,我们需要使用它来估计完成时间,也许带有确定性指示,例如使用一些 Y%
我们都曾 mock 过“还剩 X 分钟”的对话框,它似乎过于简单,但我们如何改进它呢? 实际上,输入是截至当前时间的一组下载速度,我们需要使用它来估计完成时间,也许带有确定性指示,例如使用一些 Y%
我的理解是 glmnet 采用矩阵,其中每一列都是一个解释变量。 我有一个包含约 10 个解释变量的数据框(其中一些是因子) 我怎样才能使用诸如 y~(x1*x2*x3)+(x4*x5)+x6 之类的
有没有办法估计运行 R 的时间?命令而不实际运行它或仅部分运行命令? 我知道 system.time()存在但需要运行整个命令然后它给出了花费的时间。 最佳答案 还有http://www.ats.uc
在尝试使用 libGD 在 PHP 中调整图像大小之前,我想检查是否有足够的内存来执行操作,因为“内存不足”会完全杀死 PHP 进程并且无法被捕获。 我的想法是,原始图像和新图像中的每个像素 (RGB
我有一些 VHDL 文件,我可以在 Debian 上用 ghdl 编译它们。一些人已将相同的文件改编为 ASIC 实现。算法有一个“大面积”实现和一个“紧凑”实现。我想编写更多实现,但要评估它们,我需
我在 Amazon EC2 上使用 RStudio 0.97.320 (R 2.15.3)。我的数据框有 20 万行和 12 列。 我正在尝试使用大约 1500 个参数来拟合逻辑回归。 R 使用 7%
我目前正在估算一个新项目。假设只有一名开发人员在处理它,我的高水平估计是 25 周。 实际上会有两个开发人员并行工作。减少估计的什么因素是合理的? (我意识到不会是0.5) 最佳答案 根据原始开发人员
我试图更好地理解创建 Postgres 索引所涉及的权衡。作为其中的一部分,我很想了解通常使用多少空间索引。我已通读 the docs ,但找不到这方面的任何信息。我一直在做自己的小实验来创建表和索引
我对 Azure 平台相当陌生,需要一些有关 Azure 搜索服务成本估算的帮助。每个月我们都会有大约 500GB 的文件被放入 Azure Blob 存储中。我们希望仅根据文件名使用 Azure 搜
我正在尝试最大化横截面面板数据中的数据点数量。我的矩阵结构如下,y 轴为年份,x 轴为国家/地区: A B C D 2000 NA 50 NA
如果我有两个时间序列,例如: t f1 #[1] 0.25 #> f2 #[1] 0.25 f phase_difference #[1] 0.5 这意味着时间序列相移 pi/2,因为它们应该根据
我对 Azure 平台相当陌生,需要一些有关 Azure 搜索服务成本估算的帮助。每个月我们都会有大约 500GB 的文件被放入 Azure Blob 存储中。我们希望仅根据文件名使用 Azure 搜
我使用了以下 R 包:mice、mitools 和 pROC。 基本设计:3 个预测变量度量,在 n~1,000 的数据缺失率在 5% 到 70% 之间。 1 个二进制目标结果变量。 分析目标:确定
如何使用 lsmeans 来估计两个成对对比的差异?例如——想象一个连续的 dv 和两个因子预测变量 library(lsmeans) library(tidyverse) dat % fac
我制作了一个使用 BigDecimal 的科学计算器。它有一个特别消耗资源的功能:阶乘。现在,输入任何数字都会启动计算。根据运行此代码的设备,答案会在不同的时间显示。输入像 50000 这样的巨大值!
我已经发出了 sympy 命令来求解某个方程或另一个方程。现在已经好几天了,我不知道什么时候能完成。 我可以使用 sympy 来记录调用 .solvers.solve 的进度吗?如果不是,我如何估计
最近我得到了一些 error C6020: Constant register limit exceeded at variable; more than 1024 registers needed
我是一名优秀的程序员,十分优秀!