【问题标题】:Replace "IN" with a JOIN Statement将“IN”替换为 JOIN 语句
【发布时间】:2012-02-28 09:53:01
【问题描述】:

我在从 Access 迁移到 MySQL 时再次遇到问题。

以下 SQL 语句适用于 Access

SELECT *
FROM tbl_content 
WHERE contentID IN (
     SELECT contentID
     FROM tbl_tags
     WHERE Bezeichnung IN (
              SELECT Bezeichnung
              FROM tbl_tags t2
              WHERE t2.contentID= " & contentID & ")
     AND contentID <> " & contentID & ")
AND Status = 1
ORDER BY Datum DESC LIMIT 0,5;

MySQL中,性能确实很慢。有什么建议吗?

【问题讨论】:

  • 可能您在 MySQL 上有一些您在 Access 数据库中没有的索引。
  • EXPLAIN 放在SELECT 之前。向我们展示输出。同时显示CREATE TABLE tbl_content的输出。

标签: mysql sql ms-access


【解决方案1】:

MySQL 有一个关于子查询的已知问题,它每次比较时都会根据外部查询评估它们。避开他们!这可能就是您看到 Access 性能下降的原因。

【讨论】:

    【解决方案2】:

    您已经在标题中回答了自己的问题。一般来说,MySQL 不会像 JOINS 一样优化IN (Subquery),所以最好使用JOIN

    SELECT  *
    FROM    tbl_content t1
            INNER JOIN
            (   SELECT  ContentID
                FROM    tbl_tags t1
                        INNER JOIN
                        (   SELECT  Bezeichnung 
                            FROM    tbl_tags t2 
                            WHERE   t2.contentID = " & contentID & "
                            GROUP BY Bezeichnung
                        ) t2
                            ON t1.Bezeichnung = t2.Bezeichnung
                WHERE   contentID <> " & contentID & "
                GROUP BY ContentID
            ) t2
                ON t2.ContentID = t1.ContentID
    WHERE   Status = 1
    ORDER BY Datum DESC LIMIT 0,5;
    

    还要检查相关列是否已编入索引以提高性能。

    编辑

    还有更多我认为EXISTS 在 MySQL 中可能更高效,但EXPLAIN 应该显示更多:

    SELECT  *
    FROM    tbl_content t1
    WHERE   EXISTS
            (   SELECT  1
                FROM    tbl_tags t2
                WHERE   EXISTS
                        (   SELECT  1
                            FROM    tbl_tags t3
                            WHERE   t2.contentID = " & contentID & "
                            AND     t2.Bezeichnung = t2.Bezeichnung
                        ) 
                AND     t1.ContentID = t2.ContentID
            ) 
    AND     Status = 1
    AND     t1.contentID <> " & contentID & "
    ORDER BY Datum DESC LIMIT 0,5;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 2015-03-10
      • 1970-01-01
      相关资源
      最近更新 更多