[英]Slow query SELECT … GROUP BY on two tables fields` (MySQL/InnoDB)
我对 select 订单有一个查询,对于每个订单,我需要获取它包含的产品列表以及每个产品的汇总数量。
目前它非常慢(我的设置为 10 秒),我需要加快速度。
更新:切换到 MyISAM 不是一种选择,我需要交易
目前的查询是这样的:
SELECT `Order`.*, `Product`.`id`, `Product`.`msrp`, SUM(`OrderItem`.`quantity`) AS sum
FROM `orders` AS `Order`
LEFT JOIN `order_items` AS `OrderItem` ON (`OrderItem`.`order_id` = `Order`.`id`)
LEFT JOIN `product_variations` AS `ProductVariation` ON (`OrderItem`.`product_variation_id` = `ProductVariation`.`id`)
LEFT JOIN `products` AS `Product` ON (`ProductVariation`.`product_id` = `Product`.`id`)
WHERE 1 = 1
GROUP BY `Order`.`id`, `Product`.`id`
ORDER BY `Order`.`created` DESC
LIMIT 20;
解释:
架构(截断,只剩下必填字段):
CREATE TABLE `orders` (
`id` int(11) NOT NULL auto_increment,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP,
`customer_comments` text NOT NULL,
PRIMARY KEY (`id`),
KEY `created` (`created`),
KEY `id_created` (`id`,`created`),
) ENGINE=InnoDB
CREATE TABLE `order_items` (
`id` int(11) NOT NULL auto_increment,
`order_id` int(11) NOT NULL,
`product_variation_id` int(11) NOT NULL,
`type` enum('First','Second') default NULL,
`quantity` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `item_UNIQUE` (`order_id`,`product_variation_id`,`type`),
KEY `fk_order_items_product_variations1` (`product_variation_id`),
CONSTRAINT `fk_order_items_orders1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_order_items_product_variations1` FOREIGN KEY (`product_variation_id`) REFERENCES `product_variations` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB
CREATE TABLE `product_variations` (
`id` int(11) NOT NULL auto_increment,
`product_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_product_variations_products1` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB
CREATE TABLE `products` (
`id` int(11) NOT NULL auto_increment,
`msrp` decimal(5,2) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB
服务器是 MySQL 5.0.77,表是 InnoDB。 orders
大约 75k 条记录, order_items
160k 条记录, product_variations
140k 条记录, product
- 300 条记录。
任何帮助表示赞赏。
我会尝试的第一件事是将SUM
替换为预先计算的 product_sum 表。 众所周知,InnoDB 的聚合函数速度较慢(尤其是 75k+ 行)。 您真的不想每次查询都计算这个总和(除非数据经常更改)。
使用在插入/更新订单后重新计算 product_sum 表的触发器可能会有所帮助。但不清楚此查询的上下文是什么(它是否由最终用户运行?是 web 请求还是报告?等)。
另一种选择是将引擎切换到 MyISAM(聚合速度更快),但是一个巨大的负面影响是您会丢失事务和外键约束。
尽管您的查询看起来结构良好并且连接在一起,但记录量可能是问题所在。 你有 group by 等。我会添加一个子句......
SELECT STAIGHT_JOIN... rest 的查询。
STRAIGHT_JOIN 告诉引擎按照您声明的顺序执行此操作,而不是尝试将较小的表优化为主要表,然后以某种相反的意图顺序加入。 我已经看到 STRAIGHT_JOIN 在其他几个领域的出色表现......也许它也可以帮助你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.