对于作业,我希望让我的代码更快。我使用sqlite3 c ++ API执行任务,以便最终构建一个r-tree和b-tree。
我正确地完成了任务的任务,但不幸的是它非常慢。对于我的问题,我将首先展示简单的模拟表,然后显示我的程序的简单流程。
简化表格架构:
areaTable (id int, closed int)
middleTable (nodeid int, areaid int)
nodeTable (id int, x float, y float)
我的程序流程如下:
QUERY1
SELECT id FROM areaTable WHERE closed = 1;
使用query1我将生成的id保存到向量数组中(我们称之为query1ResultsArray)。 然后使用sqlite3_prepare_v2我准备一个新的选择查询:
QUERY2
SELECT MIN(x), MIN(y)
FROM nodeTable
WHERE id IN
(
SELECT nodeid
FROM middleTable
WHERE areaid = ?
);
查询2的想法是我们发现将找到由middleTable和areaTable组合在一起的节点的最小值。我使用for循环将来自query1的单个结果绑定到query2中,如下所示:
prepare query2
begin transaction (not sure if this helps)
for (auto &id : query1ResultsArray) {
bind(id)
step(stmt)
x = column 0
y = column 1
cout << "INSERT INTO ...."
reset(stmt)
}
end transaction
finalize(stmt)
此解决方案似乎有效。它得到了继续执行任务(构建插入语句)所需的正确结果,但它非常慢。我怀疑教授希望我们的课程变得如此缓慢。
这是我的问题的背景。问题本身基本上是:
我可以将我的两个select语句组合在一起吗?通过组合select语句,我可以绕过常量绑定和重置,我希望(不知道备份它)会加快我的计划。
我尝试过以下方法:
SELECT MIN(x), MIN(y), MAX(x), MAX(y)
FROM nodeCartesian
WHERE id IN
(
SELECT nodeid
FROM waypoint
WHERE wayid IN
(
SELECT id
FROM way
WHERE closed = 1
)
);
但是这得到所有节点的最小值,因为它们没有正确地组合到各自的区域中。
P.S。我正在处理一个2D r树,所以我知道我写的不是正确的,但我只是写了我遇到的困难。此外,我尝试研究如何将内部联接应用于我的陈述,但无法弄清楚如何:(,所以如果你认为这也可以帮助我的表现,我很乐意听到它。另一件事是查询1处理2亿多行,而query2处理大约340,000行,我估计查询2完成需要大约1天。
由于
答案 0 :(得分:0)
我不确定你的架构;但是,我认为你所在地区的一个小组应该这样做
SELECT m.areaid, MIN(n.x), MIN(n.y), MAX(n.x), MAX(n.y)
FROM
nodeCartesian n
INNER JOIN waypoint wp ON n.id = wp.nodeid
INNER JOIN way w ON wp.wayid = w.id
INNER JOIN middleTable m ON n.id = m.nodeid
WHERE
w.closed = 1
GROUP BY
m.areaid
注意:在循环中多次调用SELECT查询是一个坏主意,因为每个调用都有很大的开销,这使得它非常慢。使单个查询返回所有相关行,然后在代码中循环它们要快得多。