Оптимизация небольшого MySQL Join Query - PullRequest
2 голосов
/ 08 сентября 2011

У меня есть список мест в таблице Venues и список городов / штатов в таблице Locations.Место встречи связано с кодом города, уникальным для моей организации, называемым SOYID.SOYID состоит из географической области - каждая строка в таблице Locations содержит город, штат и соответствующий SOYID. В одних строках Venues есть SOYID, в других - нет;для тех, кто этого не делает, мне нужно найти SOYID для перечисленного города и штата. Я хочу выбрать только эти объекты в определенном SOYID.

Этот запрос работает, однако он занимает несколькосекунды для загрузки;Я не думаю, что пишу запрос правильно.В настоящее время в Venues около 140 рядов, в Locations - 40 000.

    $sql = "SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
            FROM Venues AS a LEFT JOIN Locations AS c ON a.City = c.city
            WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
            OR ((c.city = a.City) AND  (c.state = a.StateAbbr) AND (c.SOYID = '" . mysql_real_escape_string($SOYID) . "'))
            ORDER BY a.Name ASC";

1 Ответ

2 голосов
/ 08 сентября 2011

Каждый раз, когда вы ссылаетесь на столбец из таблицы LEFT JOINed (c.state и c.SOYID в вашем конкретном случае) в предложении WHERE, вы заставляете это соединение вести себя как INNER JOIN. Вместо этого сделайте эти тесты частью условия соединения:

"SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
    FROM Venues AS a 
        LEFT JOIN Locations AS c 
            ON a.City = c.city
                AND a.StateAbbr = c.state
                AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "'
    WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
        OR c.SOYID IS NOT NULL /* LEFT JOIN found a matching row */
    ORDER BY a.Name ASC"

РЕДАКТИРОВАТЬ : на основе комментариев, эта версия должна позволить вам удалить требование DISTINCT:

"SELECT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
    FROM Venues AS a 
    WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
        OR EXISTS(SELECT NULL
                      FROM Locations AS c 
                      WHERE a.City = c.city
                          AND a.StateAbbr = c.state
                          AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "') 
    ORDER BY a.Name ASC"
...