mysql - 选择查询的异常 MySQL 行为

标签 mysql sql

我有 3 个表 A、B 和 C:

  • 表 A 很小(约 1000 行)。
  • 表 B 大约有 200,000 行。
  • 表 C 有大约 220 万行。

我正在运行这样的查询:

SELECT A.Id FROM A, B, C 
WHERE A.Id = B.SomeId OR (A.Id = C.SomeId AND C.SomeValue = 'X') 
INTO OUTFILE '/tmp/result.txt';
  • A.Id是表A的主键
  • B.SomeId 设置了索引
  • 编辑:C.SomeId设置了索引
  • C.SomeVal 也设置了一个索引,但它是一个只有两个可能值的 VARCHAR(1)

我以为这只需要遍历表 A(1000 行)中的每个 Id,然后可能会跨其他表进行查询(取决于 MySQL 是否短路,我不知道是否确实如此)。

但查询似乎挂起,或者至少需要很长时间。如果它只需要迭代 1000 行,比我预期的要长得多。 10 分钟后,输出文件仍然是空的。让我知道是否可以提供更多信息。

my@laptop$ mysql --version
mysql  Ver 14.14 Distrib 5.5.37, for debian-linux-gnu (i686) using readline 6.3

编辑:
我正在寻找的结果是“给我表 A 中的所有 ID,其中 ID 匹配 B.SomeId 或 ELSE Id 匹配 C.SomeId AND C.SomeValue 等于“X”。

最佳答案

OR 表达式常常使 MySQL 难以使用索引。尝试更改为 UNION:

SELECT A.id
FROM A
JOIN B ON A.id = B.SomeID
UNION
SELECT A.id
FROM A
JOIN C ON A.id = C.SomeID
WHERE C.SomeValue = 'A'

来自documentation :

Minimize the OR keywords in your WHERE clauses. If there is no index that helps to locate the values on both sides of the OR, any row could potentially be part of the result set, so all rows must be tested, and that requires a full table scan. If you have one index that helps to optimize one side of an OR query, and a different index that helps to optimize the other side, use a UNION operator to run separate fast queries and merge the results afterward.

您的查询由最后一句话描述:OR 查询的每一侧都有不同的索引。

关于mysql - 选择查询的异常 MySQL 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24765849/

相关文章:

MySQL 函数/循环

php - MySQL创建用户并授予权限脚本

php - MySQL当插入行列值对于每一行都是相同的

php - 在 mysql 中使用 where 条件选择以前的 id

mysql - SQL如何在值更改时检索第一行?

mysql - 优先选择列

mysql - codeigniter查询问题

php - 如何尽可能高效地将400k长度的json文件上传到mysql数据库?

MySql 函数没有给出正确的结果

mysql - hibernate 事务导致 mysql innodb 中的提交和后续回滚