MySQL,不在重写到左连接中
因为MySQL在MySQL,不在重写到左连接中,mysql,query-optimization,Mysql,Query Optimization,因为MySQL在查询中的性能非常差。因此,我试图使用左连接重写此查询,但我的查询结果似乎不一致。我不太确定这件事哪里出了问题 下面是我的MySQL查询: SELECT DISTINCT '' AS ID, ADNO, PDATE, REMARKS FROM AOE_tbl WHERE ADNO NOT IN (SELECT adno.meta_value AS 'ADNO' FROM
查询中的性能非常差。因此,我试图使用左连接
重写此查询,但我的查询结果似乎不一致。我不太确定这件事哪里出了问题
下面是我的MySQL查询:
SELECT DISTINCT '' AS ID,
ADNO,
PDATE,
REMARKS
FROM AOE_tbl
WHERE ADNO NOT IN
(SELECT adno.meta_value AS 'ADNO'
FROM wp_postmeta AS adno
WHERE adno.meta_key = 'adno')
AND ADNO NOT IN
(SELECT ADNO
FROM AOE_tbl
WHERE REMARKS IN ('private', 'trash')
OR STATUS = 'VOIDED')
GROUP BY ADNO;
我将其改写为:
SELECT DISTINCT '' AS ID,
AOE1.ADNO,
AOE1.PDATE,
AOE1.REMARKS
FROM AOE_tbl AOE1
LEFT JOIN wp_postmeta AS adno ON AOE1.ADNO = adno.meta_value
AND adno.meta_key = 'adno'
LEFT JOIN AOE_tbl AS AOE2 ON AOE1.ADNO = AOE2.ADNO
AND AOE2.REMARKS IN ('private', 'trash')
OR AOE2.STATUS = 'VOIDED'
WHERE adno.meta_key IS NULL
AND AOE2.REMARKS IS NULL
AND AOE2.STATUS IS NULL
GROUP BY AOE1.ADNO;
我需要帮助,看看我在上面的查询中是否遗漏了什么。
提前感谢。和
的优先级高于或
问题出在AEO2的连接条件下。请注意,添加参数将导致或
操作在和
运算符之前求值
... AOE2
on AOE2.ADNO = AOE1.ADNO
AND ( AOE2.REMARKS IN ('private', 'trash')
OR AOE2.STATUS = 'VOIDED'
)
在没有添加参数的情况下,首先计算和
运算符,然后计算或
条件。。。这意味着查询正在检查表中状态为“已作废”的任何行,而不仅仅是状态为“已匹配”的行
上述内容相当于:
... AOE2
ON ( AOE2.ADNO = AOE1.ADNO
AND AOE2.REMARKS IN ('private', 'trash')
)
OR ( AOE2.ADNO = AOE1.ADNO
AND AOE2.STATUS = 'VOIDED'
)
在这种形式下,paren是多余的。如果我们移除它们,它将是相同的。(在或
操作之前评估的和
操作
此外,WHERE子句中的反连接条件可以简化。我们保证,如果找到任何匹配行,AEO2.ADNO将不会为NULL,这意味着只有在没有找到匹配行时,AEO2.ADNO才会为NULL
就我个人而言,我会避免出现或的情况。有了适当的索引,第三个反连接的性能可能会更好
... AOE2
ON AOE2.ADNO = AOE1.ADNO
AND AOE2.REMARKS IN ('private', 'trash')
LEFT
JOIN AOE_tbl AEO3
ON AOE3.ADNO = AOE1.ADNO
AND AOE3.STATUS = 'VOIDED'
WHERE adno.meta_key IS NULL
AND AOE2.ADNO IS NULL
AND AOE3.ADNO IS NULL
和
的优先级高于或
问题在于AEO2
的连接条件。请注意,添加参数将导致或操作在和运算符之前进行评估
... AOE2
on AOE2.ADNO = AOE1.ADNO
AND ( AOE2.REMARKS IN ('private', 'trash')
OR AOE2.STATUS = 'VOIDED'
)
在没有添加参数的情况下,首先计算和
运算符,然后计算或
条件…这意味着查询正在检查表中状态为已“作废”的任何行
,而不仅仅是具有匹配的ADNO
的行
上述内容相当于:
... AOE2
ON ( AOE2.ADNO = AOE1.ADNO
AND AOE2.REMARKS IN ('private', 'trash')
)
OR ( AOE2.ADNO = AOE1.ADNO
AND AOE2.STATUS = 'VOIDED'
)
在这种形式下,参数是多余的。如果我们删除它们,它将是相同的。(在或操作之前评估的和操作
此外,WHERE子句中的反连接条件可以简化。我们保证,如果找到任何匹配行,AEO2.ADNO将不会为NULL,这意味着只有在没有找到匹配行时,AEO2.ADNO才会为NULL
就我个人而言,我会避免出现或的情况。有了适当的索引,第三个反连接的性能可能会更好
... AOE2
ON AOE2.ADNO = AOE1.ADNO
AND AOE2.REMARKS IN ('private', 'trash')
LEFT
JOIN AOE_tbl AEO3
ON AOE3.ADNO = AOE1.ADNO
AND AOE3.STATUS = 'VOIDED'
WHERE adno.meta_key IS NULL
AND AOE2.ADNO IS NULL
AND AOE3.ADNO IS NULL