【问题标题】:How to query a SQL statement which depends on other values of same table?如何查询依赖于同一张表的其他值的 SQL 语句?
【发布时间】:2017-03-28 01:04:05
【问题描述】:

我有一个包含 3 列的表(名称、objectroot_dn、distinguishedname)。这里的 distinguishedname 就像 objectroot_dn 的父级。我必须找出每个 objectroot_dn 是否存在一个孩子?

我可以使用下面的查询来做到这一点。如果有孩子,它将返回 True,如果没有,则返回 False。但我的问题是,当总数据集增加时,它需要很多时间。

例如,如果总行数为 50,000,则此查询需要 10 分钟才能完成。

由于我使用不同数据库的框架,我无法索引列。

选择 姓名, objectroot_dn, 专有名称, 案子 何时(选择计数(*) FROM(选择名称 FROM elaoucontainergeneraldetails WHERE objectroot_dn = dn.distinguishedname 限制 1) 如表 1) > 0 那么“真” 否则“错误” 结尾 FROM elaoucontainergeneraldetails AS dn WHERE objectroot_dn = 'SOME_VALUE';

请告诉我如何提高此查询的速度。

提前致谢。感谢所有帮助。

【问题讨论】:

  • 你说你不能索引列,那你就麻烦大了……(你如何创建表?)
  • 我会尝试将进程分成两部分(借助光标)。第一部分将查询并返回需要更新的记录列表(以及可能更新的内容(是/否);第二部分将遍历游标并执行更新。但是,您应该考虑执行 50,000 次更新不管你做什么都需要一些时间(虽然不应该花 10 分钟)..
  • “由于我使用不同数据库的框架,我无法索引列”是什么阻止您使用 mysql 控制台创建索引?
  • @FDavidov 在应用程序中重新实现嵌套循环连接必然比在数据库中执行更差。
  • @LaurenzAlbe 不一定。我已经多次看到这种拆分确实有效,并且在某些情况下,它的性能优于其他方法。

标签: mysql sql performance postgresql relational-database


【解决方案1】:

你可以使用 left join 或存在相同的解决方案:

SELECT
      dn.name,
      dn.objectroot_dn,
      dn.distinguishedname,
      CASE
      WHEN dn_in.objectroot_dn is not null
        THEN 'True'
      ELSE 'False'
      END
    FROM elaoucontainergeneraldetails AS dn
    LEFT JOIN elaoucontainergeneraldetails dn_in on dn_in.objectroot_dn = dn.distinguishedname
    WHERE objectroot_dn = 'SOME_VALUE';

【讨论】:

  • 如果右侧有不止一行匹配,您最终会得到多个结果行,均显示'True'
  • 是的,如果我至少有一行符合条件,那么它是真的
【解决方案2】:

EXISTS(subquery) 产生一个布尔值:

SELECT dn.name
  , dn.objectroot_dn
  , dn.distinguishedname
  , EXISTS (SELECT *
              FROM elaoucontainergeneraldetails nx
              WHERE nx.objectroot_dn = dn.distinguishedname
              )  AS truth_value
FROM elaoucontainergeneraldetails AS dn
WHERE dn.objectroot_dn = 'SOME_VALUE'
   ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2018-06-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    相关资源
    最近更新 更多