Заменить "IN" на оператор JOIN - PullRequest
0 голосов
/ 28 февраля 2012

Снова возникают проблемы при переходе с Доступ на MySQL .

Следующие операторы SQL отлично работают с Доступ :

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 производительность действительно низкая.Есть идеи о помощи?

Ответы [ 2 ]

2 голосов
/ 28 февраля 2012

MySQL имеет известную проблему с подзапросами, где он сравнивает их с внешним запросом КАЖДЫЙ РАЗ, с которым сравнивается.Избежать их!Вероятно, именно поэтому вы видите такое ухудшение доступа.

1 голос
/ 28 февраля 2012

Вы ответили на свой вопрос в заголовке.Вообще говоря, MySQL не оптимизирует IN (Subquery) и JOINS, поэтому было бы лучше использовать 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...