如何提高 MonetDB 单节点查询性能?
How to improve query performance on a single node in MonetDB?
我在 Windows 2012 服务器上安装了最新的(MonetDB 5 服务器 v11v.27.5 "Jul2017-SP1"),我正在尝试查询 table 14 亿行在合理的时间内 2-3s.
MonetDB 甚至可以做到这一点吗?我可以做些什么来提高性能?
到目前为止我所做的详细描述:
已创建 table:
CREATE TABLE t939ba ( id INT, xa INT, xb INT, ya INT, yb INT, a1 TINYINT, a2 TINYINT, a3 TINYINT, a4 TINYINT, a5 TINYINT, a6 TINYINT, a7 TINYINT, a8 TINYINT, a9 TINYINT);
加载数据:
COPY 1450000000 OFFSET 2 RECORDS INTO tbl FROM 'D:\es_export\file.csv'
USING DELIMITERS ',' NULL AS '' LOCKED;
运行查询:
SELECT COUNT(DISTINCT id) FROM tbl WHERE a1=22
AND xb>=143455 AND yb>=90911 AND xa<=143615 AND ya<=91007
AND a2 IN (2, 3, 4) AND a3 IN (0, 1, 2, 3, 4) AND a4 IN (0, 1, 2)
AND a5 IN (-1, 1, 2, 3, 4, 5, 6, 7) AND a6 IN (-1, 11, 12, 13, 14);
当我第一次 运行 查询时花费了 (14m 52s),第二次 运行 相同的查询花费了 (3m 23s),同一查询的第 3 个连续 运行 花费了 (14s),稍微重新排列的查询花费了 (3m 11s ).
托马斯,
总的来说,我认为这应该是可以的。鉴于很少的信息,很难说为什么不在您的情况下。
您能否分享以下(部分)信息:
- 硬件特性:CPU(类型、#cores、时钟速度)、RAM 容量、I/O 系统类型(单个 HDD、HDD RAID、SSD、NVMe,...)
此外,要了解时间的去向,需要了解 MonetDB 生成和使用的查询计划,并分析查询。
您能否生成查询的 PLAN(逻辑计划)、EXPLAIN(物理计划)和 TRACE(执行时间分析)(有关详细信息,请参阅 https://www.monetdb.org/Documentation/Manuals/SQLreference/Runtime)并分享它们(如果没有,则在此处分享)通过电子邮件)?
您可以尝试在非Windows(最好是Linux)系统上运行吗?关于 Windows ...
的性能,我们没有最好的体验
谢谢!
斯蒂芬
ps:
您也可以尝试如下稍微修改您的查询,看看这个 helps:
SELECT COUNT(DISTINCT id) FROM tbl WHERE
a1=22
AND xb>=143455
AND yb>=90911
AND xa<=143615
AND ya<=91007
AND a2 between 2 and 4
AND a3 between 0 and 4
AND a4 between 0 and 2
AND a5 IN (-1, 1, 2, 3, 4, 5, 6, 7)
AND a6 IN (-1, 11, 12, 13, 14)
;
甚至
SELECT COUNT(DISTINCT id) FROM tbl WHERE
a1=22
AND xb>=143455
AND yb>=90911
AND xa<=143615
AND ya<=91007
AND a2 between 2 and 4
AND a3 between 0 and 4
AND a4 between 0 and 2
AND (a5 = -1 or a5 between 1 and 7)
AND (a6 = -1 or a6 between 11 and 14)
;
此外,您能否检查并分享您的以下数据统计信息:
select
count(*),
count(id), count(distinct id),
count(xa), count(distinct xa),
count(xb), count(distinct xb),
count(ya), count(distinct ya),
count(yb), count(distinct yb),
count(a1), count(distinct a1),
count(a2), count(distinct a2),
count(a3), count(distinct a3),
count(a4), count(distinct a4),
count(a5), count(distinct a5),
count(a6), count(distinct a6),
count(a7), count(distinct a7),
count(a8), count(distinct a8),
count(a9), count(distinct a9)
from tbl
;
select count(*) from tbl where a1=22;
select count(*) from tbl where xb>=143455;
select count(*) from tbl where yb>=90911;
select count(*) from tbl where xa<=143615;
select count(*) from tbl where ya<=91007;
select count(*) from tbl where a2 IN (2, 3, 4);
select count(*) from tbl where a3 IN (0, 1, 2, 3, 4);
select count(*) from tbl where a4 IN (0, 1, 2);
select count(*) from tbl where a5 IN (-1, 1, 2, 3, 4, 5, 6, 7);
select count(*) from tbl where a6 IN (-1, 11, 12, 13, 14);
托马斯,
感谢您的计划和痕迹。
我看到您将修改后的查询与范围谓词而不是 IN 谓词一起使用,并且该查询现在 运行s 在 "a mere" ~39 s(与 ~15 分钟相比)---要么是因为范围谓词的评估比 IN 谓词更有效,或者因为正如 Martin 指出的那样,后来的 运行 查询受益于 MonetDB 在评估第一个查询时自动构建的索引,或者因为两者。
无论如何,运行宁 a/each 查询 (-version) 不止一次是查看自动构建索引的可能效果的好主意。
此外,我发现您确实有一台 34 核机器,或者您的机器每个核心有 "only" 2 GB RAM --- 考虑到您有大约 42 GB 的数据集,这不算太多,其中每列的大小约为 1.5 GB 至 6 GB ...
因此,查询没有 运行ning 快于 ~39 秒的主要原因可能是 I/O activity 由于 "lack" 内存。
最佳,
斯蒂芬
ps:
您可以检查是否针对此特定查询,减少(甚至避免)多核并行度 helps 以减少 I/O 抖动:
使用
禁用 MonetDB 的 "mitosis" 优化器后尝试 运行ning 您的查询
set optimizer='no_mitosis_pipe';
您可以使用
重新启用完整的多核并行性
set optimzer='default_pipe';
最佳,
斯特凡
我在 Windows 2012 服务器上安装了最新的(MonetDB 5 服务器 v11v.27.5 "Jul2017-SP1"),我正在尝试查询 table 14 亿行在合理的时间内 2-3s.
MonetDB 甚至可以做到这一点吗?我可以做些什么来提高性能?
到目前为止我所做的详细描述:
已创建 table:
CREATE TABLE t939ba ( id INT, xa INT, xb INT, ya INT, yb INT, a1 TINYINT, a2 TINYINT, a3 TINYINT, a4 TINYINT, a5 TINYINT, a6 TINYINT, a7 TINYINT, a8 TINYINT, a9 TINYINT);
加载数据:
COPY 1450000000 OFFSET 2 RECORDS INTO tbl FROM 'D:\es_export\file.csv' USING DELIMITERS ',' NULL AS '' LOCKED;
运行查询:
SELECT COUNT(DISTINCT id) FROM tbl WHERE a1=22 AND xb>=143455 AND yb>=90911 AND xa<=143615 AND ya<=91007 AND a2 IN (2, 3, 4) AND a3 IN (0, 1, 2, 3, 4) AND a4 IN (0, 1, 2) AND a5 IN (-1, 1, 2, 3, 4, 5, 6, 7) AND a6 IN (-1, 11, 12, 13, 14);
当我第一次 运行 查询时花费了 (14m 52s),第二次 运行 相同的查询花费了 (3m 23s),同一查询的第 3 个连续 运行 花费了 (14s),稍微重新排列的查询花费了 (3m 11s ).
托马斯,
总的来说,我认为这应该是可以的。鉴于很少的信息,很难说为什么不在您的情况下。 您能否分享以下(部分)信息:
- 硬件特性:CPU(类型、#cores、时钟速度)、RAM 容量、I/O 系统类型(单个 HDD、HDD RAID、SSD、NVMe,...)
此外,要了解时间的去向,需要了解 MonetDB 生成和使用的查询计划,并分析查询。
您能否生成查询的 PLAN(逻辑计划)、EXPLAIN(物理计划)和 TRACE(执行时间分析)(有关详细信息,请参阅 https://www.monetdb.org/Documentation/Manuals/SQLreference/Runtime)并分享它们(如果没有,则在此处分享)通过电子邮件)?
您可以尝试在非Windows(最好是Linux)系统上运行吗?关于 Windows ...
的性能,我们没有最好的体验谢谢!
斯蒂芬
ps:
您也可以尝试如下稍微修改您的查询,看看这个 helps:
SELECT COUNT(DISTINCT id) FROM tbl WHERE
a1=22
AND xb>=143455
AND yb>=90911
AND xa<=143615
AND ya<=91007
AND a2 between 2 and 4
AND a3 between 0 and 4
AND a4 between 0 and 2
AND a5 IN (-1, 1, 2, 3, 4, 5, 6, 7)
AND a6 IN (-1, 11, 12, 13, 14)
;
甚至
SELECT COUNT(DISTINCT id) FROM tbl WHERE
a1=22
AND xb>=143455
AND yb>=90911
AND xa<=143615
AND ya<=91007
AND a2 between 2 and 4
AND a3 between 0 and 4
AND a4 between 0 and 2
AND (a5 = -1 or a5 between 1 and 7)
AND (a6 = -1 or a6 between 11 and 14)
;
此外,您能否检查并分享您的以下数据统计信息:
select
count(*),
count(id), count(distinct id),
count(xa), count(distinct xa),
count(xb), count(distinct xb),
count(ya), count(distinct ya),
count(yb), count(distinct yb),
count(a1), count(distinct a1),
count(a2), count(distinct a2),
count(a3), count(distinct a3),
count(a4), count(distinct a4),
count(a5), count(distinct a5),
count(a6), count(distinct a6),
count(a7), count(distinct a7),
count(a8), count(distinct a8),
count(a9), count(distinct a9)
from tbl
;
select count(*) from tbl where a1=22;
select count(*) from tbl where xb>=143455;
select count(*) from tbl where yb>=90911;
select count(*) from tbl where xa<=143615;
select count(*) from tbl where ya<=91007;
select count(*) from tbl where a2 IN (2, 3, 4);
select count(*) from tbl where a3 IN (0, 1, 2, 3, 4);
select count(*) from tbl where a4 IN (0, 1, 2);
select count(*) from tbl where a5 IN (-1, 1, 2, 3, 4, 5, 6, 7);
select count(*) from tbl where a6 IN (-1, 11, 12, 13, 14);
托马斯,
感谢您的计划和痕迹。 我看到您将修改后的查询与范围谓词而不是 IN 谓词一起使用,并且该查询现在 运行s 在 "a mere" ~39 s(与 ~15 分钟相比)---要么是因为范围谓词的评估比 IN 谓词更有效,或者因为正如 Martin 指出的那样,后来的 运行 查询受益于 MonetDB 在评估第一个查询时自动构建的索引,或者因为两者。
无论如何,运行宁 a/each 查询 (-version) 不止一次是查看自动构建索引的可能效果的好主意。
此外,我发现您确实有一台 34 核机器,或者您的机器每个核心有 "only" 2 GB RAM --- 考虑到您有大约 42 GB 的数据集,这不算太多,其中每列的大小约为 1.5 GB 至 6 GB ...
因此,查询没有 运行ning 快于 ~39 秒的主要原因可能是 I/O activity 由于 "lack" 内存。
最佳,
斯蒂芬
ps:
您可以检查是否针对此特定查询,减少(甚至避免)多核并行度 helps 以减少 I/O 抖动:
使用
set optimizer='no_mitosis_pipe';
您可以使用
重新启用完整的多核并行性set optimzer='default_pipe';
最佳,
斯特凡