如何在c ++

时间:2017-11-26 18:38:35

标签: c++ sql performance sqlite

对于作业,我希望让我的代码更快。我使用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天。

由于

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查询是一个坏主意,因为每个调用都有很大的开销,这使得它非常慢。使单个查询返回所有相关行,然后在代码中循环它们要快得多。