【发布时间】:2016-08-05 16:41:24
【问题描述】:
您好,我有一个产品类别数据库,其中产品和类别使用第三个表具有多对多关系,例如。产品分类。现在,我在数据库上运行一个查询,以获取属于类别 ID 数组中给定类别的所有产品,让我们看以下示例:
SELECT * FROM products p JOIN product_category pc ON p.id = pc.product_id
WHERE pc.category_id IN (1,2,3,4,5,6) GROUP BY p.id LIMIT 0,40
products 表有大约 23k 行,product_category 表有 26k 行。
通常,WHERE IN 子句中使用的类别 ID 数组包含更多元素。
现在这个查询需要 300 毫秒 来获取结果。如果我删除 GROUP BY 子句,那么查询只需要 2ms 来获取结果。
更完整的查询如下:
select * from `products` inner join `product_category` on `products`.`id` = `product_category`.`product_id`
where `product_category`.`category_id` in ('1', '2', '3', '4', '5', '6', '7',
'8', '44', '155', '156', '157', '158', '159', '160', '161', '162', '168', '169', '171', '172', '173', '174', '175', '176',
'178', '179', '180', '181', '182', '183', '184', '185', '186', '189', '190', '191', '192', '193', '194', '195', '196',
'197', '198', '199', '200', '201', '202', '203', '204', '205', '206', '207', '208', '209', '213', '215', '216', '217',
'218', '219', '230', '231', '232', '233',
'234', '235', '236', '237', '240', '241',
'242', '243', '244', '245', '246', '247',
'248', '249', '250', '251', '252', '253',
'254', '255', '256', '257', '258', '259',
'260', '261', '325', '326', '327', '328',
'334', '335', '336', '337', '338', '339', '340', '341', '342', '343', '344') and `products`.`is_visible` = '1'
group by `product_category`.`product_id`
order by `popularity` desc, `popularity` desc limit 40 offset 0
查询说明如下:
所以,我的问题是,是否有办法专门优化查询组,以便加载结果不会花费太长时间。
【问题讨论】:
-
既然你没有聚合,你试过
SELECT DISTINCT p.*吗? -
@Uueerdo 是的,我有,没有任何变化,使用 Select Distinct 的查询与使用 group by 的时间差不多。谢谢
-
你永远不应该使用 group by 结构,因为它不能保证在你没有在 group by 中指定的字段中总是给出相同的结果。仅仅因为您可以做某事并不意味着您应该这样做。按照所有其他数据库所需的方式正确使用 group by。当你有一个连接时,也永远不要使用 SELECT *,因为它返回的数据比你需要的多(连接字段是重复的),这会导致查询速度变慢。这两个语法问题都是 SQL 反模式,如果你试图让真正了解数据库的人通过代码审查,你会不及格。
-
@HLGEM 感谢您提供的建议,选择中的 * 用于简洁。作为数据库专家,您能回答我的问题吗?