【问题标题】:Inefficient way of getting information from Database (java, sql)从数据库(java,sql)获取信息的低效方式
【发布时间】:2014-09-30 13:28:57
【问题描述】:

我在包含文件夹/文件的数据库中有一个表。每个文件夹可以包含多个文件和文件夹,其中可以包含更多文件夹等。我的表有 3 个重要属性。

  1. 身份证
  2. 父代
  3. 姓名

现在我要做的是在获得文件/文件夹的 id 时获取文件/文件夹的完整路径。(顶级文件夹 parentid 为空)

问题是我能看到的唯一方法就是这样做

while (continue) {
    "select (parentid) from table where id = (id)"

    if(parentid equals null) {
        continue is false;
    } else {
        path += "/" + parentid(name);
    }
}

对不起可怜的psudo

但它会继续获取父文件夹,直到不再存在,然后我可以制作我的路径

但这似乎是一种非常低效的方法。特别是如果我必须处理数十万个文件并且我必须为每个文件/文件夹执行此操作。

会不会有更简单更高效的sql查询。

【问题讨论】:

  • 除非你试过,不然怎么知道效率低?
  • tbh 我只是假设,对数据库的许多调用会是?
  • 如果您真的想提高效率(完整路径的单个查询),您可能必须更改存储数据的方式。看看Joe Celko's Trees and Hierarchies in SQL for Smarties
  • 如果事实证明这不是高性能的,您可以使用连接搜索深度为 2,这可能会花费一半的时间。但是在 Java 性能调优方面工作了十多年,我建议您不要试图猜测您的性能瓶颈是什么,因为它很可能不是您在测量时所想的那样。
  • 使用现代 DBMS,您可以使用单个 SQL 语句来完成 - 但对于 MySQL,您会遇到类似的问题(无论是存储过程还是 Java 代码 - 解决方案本身基本相同)

标签: java mysql sql performance jdbc


【解决方案1】:

您可以在从数据库内部运行的函数或存储过程中执行此操作。这将减少对数据库的调用量和正在传输的数据。大多数主要数据库都支持准备好的语句,因此您的数据库应该支持它。

【讨论】:

    【解决方案2】:

    如何使用递归 SQL 并在 1 个 DB 调用中获得完整的树:

    SELECT 
        id, 
        name, 
        @pv:=parentid as 'parentid' 
    FROM
        table1
    JOIN
        (SELECT @pv:=1) tmp
    WHERE id=@pv;
    

    Demo

    当然你需要使用PreparedStatement来进一步提升性能。

    【讨论】:

    • 你能再解释一下吗? @pv 然后在 @pv=1 处加入
    • @hat_to_the_back 1 in @pv:=1 是起点。因此,当您运行上述查询时,它将拉出 1 的所有祖先。@pv 是我们存储当前行的 parentid 的临时位置。我希望这能澄清你的疑问。
    【解决方案3】:

    要遵循的原则之一是永远不要动态计算可以设置的值。

    在你的情况下,考虑做一些事情,比如向你的表中添加一个新字段(fullparentpath)。

    那么就可以直接查询得到完整路径了。

    【讨论】:

    • 很遗憾我无法更改数据库
    猜你喜欢
    • 2010-10-07
    • 2012-10-31
    • 1970-01-01
    • 2016-09-03
    • 2012-07-13
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    相关资源
    最近更新 更多