【问题标题】:Optimizing Small MySQL Join Query优化小型 MySQL 连接查询
【发布时间】:2011-11-13 01:58:35
【问题描述】:

我在场地表中有一个场地列表,在位置表中有一个城市/州的列表。场地与我的组织唯一的区号相关联,称为 SOYID。 SOYID 由一个地理区域组成 - Locations 表中的每一行都有一个城市、州和相应的 SOYID。 有些场地行有 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";

【问题讨论】:

    标签: php mysql join query-optimization


    【解决方案1】:

    任何时候您在 WHERE 子句中引用 LEFT JOINed 表中的列(c.statec.SOYID 在您的特定情况下),您强制该连接表现得像一个 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"
    

    编辑:基于 cmets,此版本应该允许您删除 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"
    

    【讨论】:

    • 我猜他现在可以放弃DISTINCT,不是吗?或者使用GROUP BY a.VenuID 而不是DISTINCT
    • @ypercube:是的,我认为放弃DISTINCT 可能是安全的。
    • 如果我放弃独特的,我仍然会得到重复的行,所以不,我仍然需要保持独特的。谢谢!
    • @John:我添加了一个替代查询,应该消除对不同的需求。
    猜你喜欢
    • 2017-04-04
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2010-10-31
    • 2020-02-14
    相关资源
    最近更新 更多