我实际上已经设法让这个工作,但想知道是否有任何 Guru 能够提供更优化的方法:
SELECT `cfc`.`card_face_id`
FROM `card_face_color` AS `cfc`
INNER JOIN `color` AS `c` ON c.color_id = cfc.color_id
WHERE c.c_url IN ('black', 'blue')
AND card_face_id NOT IN (
SELECT `cfc`.`card_face_id`
FROM `card_face_color` AS `cfc`
INNER JOIN `color` AS `c` ON cfc.color_id = c.color_id
WHERE c.c_url NOT IN ('black', 'blue')
)
GROUP BY `cfc`.`card_face_id`
HAVING (COUNT(DISTINCT c.c_url) = 2)
本质上,我正在尝试选择所有包含黑色和蓝色的 card_faces,但没有其他颜色(每个 card_face 可能最多 5 个)。尝试使用内部连接来实现,但这慢了近 25 倍。我对我的索引很满意,我只是对 Have 子句没有经验。
更新
EXPLAIN
针对查询运行会显示这一点(对格式表示歉意)。
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY c index PRIMARY,c_url c_url 50 NULL 10 Using where; Using index; Using temporary; Using filesort
1 PRIMARY cfc ref color_id color_id 1 site.co.uk.c.color_id 1156 Using where; Using index
2 SUBQUERY c range PRIMARY,c_url c_url 50 NULL 9 Using where; Using index
2 SUBQUERY cfc ref color_id color_id 1 site.co.uk.c.color_id 1156 Using index