SQL Join - 需要解释

3

请考虑以下查询:

SELECT A.*, 
    GROUP_CONCAT(DISTINCT CONCAT(I.Image, '@', I.Local, '@', I.Primary) SEPARATOR ',') AS _Images, 
    GROUP_CONCAT(DISTINCT H.LocationId SEPARATOR ',') AS _Hierarchy, 
    GROUP_CONCAT(DISTINCT Am.AmenityId SEPARATOR ',') AS _Amenities 
FROM Ads as A 
    LEFT JOIN ImagesTable as I ON I.AdId = A.AdId 
    LEFT JOIN HierarchyTable as H ON H.AdId = A.AdId 
    LEFT JOIN AmenitiesTable as Am ON Am.AdId = A.AdId 
WHERE A.AdId IN (1,2,3,4,5,6,7,8,9,10) 
GROUP BY A.AdId

假设表Ads有约1000000行。当使用MySQL运行此查询时,MySQL会如何处理该查询? 它会在表Ads的~1000000行上处理JOIN操作吗?还是只在查询末尾提供的特定ID上处理它? 在where子句中指定200行时,像这样的查询对我来说需要大约0.9秒,我正在尝试加快它的速度。这就是为什么我想知道是否有任何方法可以加快此查询,例如通过告诉MySQL仅处理所需的行,而不是整个表Ads

3
在MySQL中,您可以使用“EXPLAIN SELECT ...”来查看MySQL在语句上的运作方式。 - DaKirsche
告诉MySQL仅处理所需的行,而不是整个表Ads。表Ads出现在LEFT JOIN的左侧,这意味着在连接级别上,所有来自Ads的行都出现在结果集中。但是MySQL还会尽可能地处理WHERE子句与连接子句一起工作,以避免为不会进入最终结果集的行而工作。在Ads表的AdId列上的索引有助于过滤(WHERE子句)和连接(A.AdId出现在ON条件中)。H.AdID和Am.AdId同理。 - axiac
所有这些索引都已经存在了,不幸的是。:( - Adam Baranyai
是的,WHERE A.AdId IN ...和连接只会访问所需的行(因此特别是对于您的ads表,它将仅访问具有A.AdId IN (1,2,3,4,5,6,7,8,9,10)的行)-如果您在表上有正确的索引。如果没有添加您的explain输出和至少使用的索引的索引定义,则由您决定它们是否正确。在Ads中,每个AId是否有多于1行?如果您的其他表很小,那么10行不应该需要1秒钟。顺便说一句:使用GROUP BY A.AdIdselect A.*可能无法给您预期的结果。 - Solarflare
1个回答

0

当字段A.AdId被索引时,数据库引擎将仅在索引存储中搜索所有A.AdId以获取完整表中的位置行。 => 快速

当字段A.AdId未被索引时,数据库引擎将解析完整表中的所有行以搜索所有A.AdId。 => 非常缓慢

当数据库引擎获取A.AdId时,它们将用于与另一个表联接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接