我试图提高查询中的效果,该查询涉及获取属于任何类别列表的所有产品:
CREATE TABLE `shop_products` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`slug` varchar(125) NOT NULL,
`on_sale` tinyint(3) unsigned NOT NULL,
`deleted` tinyint(4) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`updated_date` datetime DEFAULT NULL
PRIMARY KEY (`id`),
KEY `created_date` (`created_date`),
KEY `slug` (`slug`),
KEY `updated_date` (`updated_date`),
KEY `on_sale_deleted` (`on_sale`,`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `shop_product_terms` (
`product_id` bigint(20) NOT NULL,
`term_id` int(11) NOT NULL,
KEY `term_id` (`term_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
选择属于任何给定类别列表的产品(未删除和销售):
SELECT p.id
FROM shop_products AS p
INNER JOIN shop_product_terms AS pt ON p.id=pt.product_id
WHERE
(pt.term_id=93 OR pt.term_id=97) AND
p.on_sale=1 AND p.deleted IS NULL
ORDER BY created_date DESC, updated_date DESC LIMIT 55, 10
目前执行时间为0.1秒。致电EXPLAIN
:
id select_type table partitions type possible_keys key key_len ref rows Extra
-----------------------------------------------------------------------------------------------------------------
1 SIMPLE pt NULL range term_id term_id 4 NULL 362 Using where; Using temporary; Using filesort
1 SIMPLE p NULL eq_ref PRIMARY,on_sale PRIMARY 8 pt.product_id 1 Using where
我注意到(pt.term_id=93 OR pt.term_id=97)
部分正在减缓查询速度(因为OR我猜测,因为类型=范围)。
有什么方法可以重写这个查询来改进这里的东西吗?
编辑:@Alex
提出的替代查询的EXPLAIN结果id select_type table partitions type possible_keys key? key_len? ref? rows? Extra?
1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 363 Using temporary; Using filesort
1 PRIMARY p NULL eq_ref PRIMARY,on_sale_deleted PRIMARY 8 pt.product_id 1 Using where
2 DERIVED shop_product_terms NULL range term_id term_id 4 NULL 362 Using where
第二次编辑:
id select_type table partitions type possible_keys key? key_len? ref? rows? Extra?
1 PRIMARY p NULL ref on_sale_deleted on_sale_deleted 3 const,const 3502 Using where; Using filesort
2 DEPENDENT SUBQUERY shop_product_terms NULL range term_id term_id 4 NULL 362 Using where
答案 0 :(得分:0)
你要检查这是否真的更快。
SELECT p.id
FROM shop_products AS p
INNER JOIN shop_product_terms AS pt ON p.id=pt.product_id
WHERE
pt.term_id IN (93, 97) AND
p.on_sale=1 AND p.deleted IS NULL
ORDER BY created_date DESC, updated_date DESC LIMIT 55, 10
答案 1 :(得分:0)
只是为了提高性能,你可以:
SELECT p.id
FROM shop_products as p
INNER JOIN
(SELECT
product_id
FROM
shop_product_terms
WHERE term_id IN (93,97)
) AS pt
ON p.id=pt.product_id
WHERE
p.on_sale=1 AND p.deleted IS NULL
ORDER BY created_date DESC, updated_date DESC LIMIT 55, 10
编辑,因为您为我发布了解释声明,我们可以尝试这种方式:
SELECT p.id
FROM shop_products AS p
WHERE
p.id IN (SELECT
product_id
FROM
shop_product_terms
WHERE term_id IN (93,97)
)
AND
p.on_sale=1 AND p.deleted IS NULL
ORDER BY created_date DESC, updated_date DESC LIMIT 55, 10