【问题标题】:Where clause using key column still gives an error使用键列的 where 子句仍然给出错误
【发布时间】:2017-03-22 13:41:54
【问题描述】:

我有一个表用作从另一个表中查找外键。该表非常简单,包含一个带有主键的 ID 列和一个 JSON 列。我希望从此表中删除废弃的条目。

我尝试运行此脚本:

DELETE 
FROM `ate`.`test_configuration`
WHERE `ate`.`test_configuration`.`ID` NOT IN (SELECT DISTINCT `ate`.`index`.`TestID` from `ate`.`index`);

但遇到一个错误,说明我没有使用使用键列的 where 子句:

错误代码:1175。您正在使用安全更新模式,并且您尝试更新没有使用 KEY 列的 WHERE 的表 要禁用安全模式,请切换 Preferences -> SQL Editor 中的选项并重新连接。

这很令人困惑,因为我的 where 子句确实使用了主键列。我知道我可以disable safe mode as part of my script 作为一种解决方法,但仍然想了解我为什么会收到此错误。如果可能,我想避免不安全的更新。

【问题讨论】:

  • 也许这个答案可以帮助你理解stackoverflow.com/a/18767430/2294163
  • 我知道这是问题所在,但我正在尝试实施第一个解决方案而不是第二个解决方案。我的 where 子句按照他们的建议使用索引。

标签: mysql


【解决方案1】:

我相信优化器只是无法有效地使用索引来进行此类查询 - 所以它会进行全表扫描。

test_configuration 中有多少行,其中有多少会被删除?

(您可能会尝试使用索引提示来强制优化器使用索引进行查询,只是不确定您的 mysql 版本是否支持它们)。

【讨论】:

  • 这张桌子很小。表中有大约 600 行,我试图删除其中的 400 行(主要是相同数据的转换版本)。虽然我使用的是支持索引提示的 MySql 5.7.11,但它们似乎只适用于 select 语句。安全查询错误是关于优化还是数据完整性?我的印象是需要密钥的主要原因是验证您正在更改您想要更改的行(这将由密钥唯一标识)。
  • 我相信它的实现非常简单 - 如果没有使用索引 - 会生成警告。从优化器的角度来看 - 如果大部分行将被删除,则只进行表扫描会更简单。我 100% 确信忽略小表的这个特殊警告是安全的。
  • 很抱歉长时间的回复延迟,我没​​有通知我这些 cmets。 ID 是主键,因此具有主索引。这是UUID in binary(16) format 我的问题不是关于如何解决这个问题,而是更多关于它为什么会发生。当我与表的主键进行比较时,错误根本不应该存在。
  • 我想我不理解您的说法,即不使用索引直接导致错误,因为这根本不是错误所说的。它没有提到索引。我不明白为什么它不使用索引,因为这个查询所需的所有数据都应该在那里,但更重要的是我不明白为什么索引与这个错误有关。如果你是对的,可能没有解决方案,但我已经找到了解决方法,但我真的很讨厌在不完全了解情况的情况下实施这些事情,
  • 我可以想到引入“安全更新模式”的两个原因: 1. 没有索引的更新会在各种情况下对巨大的表造成重大的性能和锁定影响。 2. 这可能表明用户不了解他们在做什么。这两者都与你的情况无关。是的 - 我认为服务器不够聪明,无法区分索引存在的情况,但由于优化器的选择而没有使用。 (也许只是消息中的措辞令人困惑)。所以是的 - 我认为你应该在这种情况下解决它并忘记
猜你喜欢
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多