【问题标题】:Absolute beginner, trying to LIMIT & ORDER a DELETE/JOIN query in MySQL绝对初学者,尝试在 MySQL 中限制和订购 DELETE/JOIN 查询
【发布时间】:2019-05-15 12:15:31
【问题描述】:

我收到了一个 MySQL 查询,用于删除数百万个我试图添加 LIMIT 的整体,这也是 ASC 的 ORDERS。我不知道自己在做什么,而且我很困惑。

据我了解,您无法限制多表 DELETE,但我发现绕过此问题的解决方案过于复杂,我无法自行调整。

DELETE a,b,c
FROM wp_posts a
LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id )
LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id )
LEFT JOIN wp_term_taxonomy d ON ( d.term_taxonomy_id = b.term_taxonomy_id )
LEFT JOIN wp_terms e ON ( e.term_id = d.term_id )
WHERE d.taxonomy = 'edd_log_type' AND a.post_type = 'edd_log' AND e.term_id = 167
ORDER BY ID ASC LIMIT 100;

期望:我正在尝试构建一个查询,该查询将查找并删除最旧的 100 个条目。我设置了一个 LIMIT,因为正在处理的条目数量(数百万)会超时查询。

实际结果:据我所知,由于 LIMIT 不适用于多表删除导致的语法错误。

【问题讨论】:

  • 这是一个奇怪的要求。你为什么要这样做?
  • @Strawberry 目的是慢慢地从最旧到最新删除这些条目 - 限制是阻止查询超时,因为它与很多人一起工作
  • 我不明白。如果您只是要在数据集上“切入”直到它全部消失,为什么不直接放弃表格呢?
  • @Strawberry 在所有被访问的表中都有重要信息,但这些表中也有一些条目是无用的日志,它们正在使数据库膨胀——据我所知,这个查询的目标和删除那些日志条目
  • 在这些情况下,通常最好创建新表,只保留您想要保留的信息,然后删除/归档旧表,然后重命名新表。

标签: mysql join sql-delete


【解决方案1】:

您不应该在 where 子句中使用与左连接表相关的列,因为将 where 用作内连接 在这些情况下,您应该在 ON 子句中移动相关条件

对于删除(基于您的代码),您可以将您的 delete statemente 加入到返回您需要的 100 id 的查询中

  delete a,b,c 
  FROM wp_posts a
  LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id )
  LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id )
  LEFT JOIN wp_term_taxonomy d ON ( d.term_taxonomy_id = b.term_taxonomy_id ) AND d.taxonomy = 'edd_log_type'
  LEFT JOIN wp_terms e ON ( e.term_id = d.term_id ) AND e.term_id = 167
  INNER JOIN  ( 

      select a.id 
      FROM wp_posts a
      LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id )
      LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id )
      LEFT JOIN wp_term_taxonomy d ON ( d.term_taxonomy_id = b.term_taxonomy_id ) AND d.taxonomy = 'edd_log_type'
      LEFT JOIN wp_terms e ON ( e.term_id = d.term_id ) AND e.term_id = 167
      WHERE a.post_type = 'edd_log'
      ORDER BY ID ASC 
      LIMIT 100

  ) t ON t.id = a.id 
  WHERE AND a.post_type = 'edd_log'

正如草莓所建议的那样,删除更好的是使用内连接(你不能删除不匹配的行)

  delete a,b,c 
  FROM wp_posts a
  INNER  JOIN wp_term_relationships b ON ( a.ID = b.object_id )
  INNER  JOIN wp_postmeta c ON ( a.ID = c.post_id )
  INNER  JOIN wp_term_taxonomy d ON ( d.term_taxonomy_id = b.term_taxonomy_id ) AND d.taxonomy = 'edd_log_type'
  INNER  JOIN wp_terms e ON ( e.term_id = d.term_id ) AND e.term_id = 167
  INNER JOIN  ( 

      select a.id 
      FROM wp_posts a
      INNER  JOIN wp_term_relationships b ON ( a.ID = b.object_id )
      INNER  JOIN wp_postmeta c ON ( a.ID = c.post_id )
      INNER  JOIN wp_term_taxonomy d ON ( d.term_taxonomy_id = b.term_taxonomy_id ) AND d.taxonomy = 'edd_log_type'
      INNER  JOIN wp_terms e ON ( e.term_id = d.term_id ) AND e.term_id = 167
      WHERE a.post_type = 'edd_log'
      ORDER BY ID ASC 
      LIMIT 100

  ) t ON t.id = a.id 
  WHERE AND a.post_type = 'edd_log'

【讨论】:

  • 感谢您的回答。我已尝试您的查询并收到以下错误:#1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 15 行的 'AND a.post_type = 'edd_log' ORDER BY ID ASC LIMIT 100 ) t ON' 附近使用正确的语法
  • 这个解决方案似乎有效,非常感谢您的帮助!我有兴趣学习,所以我很好奇,为什么下面的查询块被使用了两次?从 wp_posts a LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) LEFT JOIN wp_postmeta c ON (a.ID = c.post_id) LEFT JOIN wp_term_taxonomy d ON (d.term_taxonomy_id = b.term_taxonomy_id) AND d.taxonomy = 'edd_log_type' LEFT JOIN wp_terms e ON (e.term_id = d.term_id) AND e.term_id = 167
  • LEFT JOIN 删除?我需要很多更多的咖啡
  • @Strawberry 如果你有一点咖啡,我也需要。 .. 回答也更新了您的建议
猜你喜欢
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多