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在
查询中的性能非常差。因此,我试图使用
左连接
重写此查询,但我的查询结果似乎不一致。我不太确定这件事哪里出了问题

下面是我的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