【发布时间】:2020-06-28 12:52:53
【问题描述】:
我在 Laravel 中的代码是:
Car::selectRaw('*,
MIN(car_prices.price) AS min_price,
MAX(car_prices.price) AS max_price,
MAX(car_prices.updated_at) AS latest_update')
->leftJoin('car_prices', 'car_prices.car_id', 'cars.id')
->groupBy('car_prices.car_id')
->orderBy('latest_update', 'desc')
->paginate(10);
需要很长时间才能运行到抛出错误:
最长执行时间超过 60 秒
cars 表中的记录数为 100,000 和 car_prices 中的 6,000,000。
表格结构:
CREATE TABLE `cars` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=110001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
CREATE TABLE `car_prices` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`car_id` bigint(20) unsigned NOT NULL,
`price` decimal(8,2) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `car_prices_car_id_foreign` (`car_id`)
) ENGINE=MyISAM AUTO_INCREMENT=5506827 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
查询:
select count(*) as aggregate
from `cars`
left join `car_prices`
on `car_prices`.`car_id` = `cars`.`id`
group by `car_prices`.`car_id`;
select *,
MIN(car_prices.price) AS min_price,
MAX(car_prices.price) AS max_price,
MAX(car_prices.updated_at) AS latest_update from `cars`
left join `car_prices`
on `car_prices`.`car_id` = `cars`.`id`
group by `car_prices`.`car_id`
order by `latest_update` desc
limit 10
offset 0;
如何优化它?我应该缓存数据吗?还是有比这更好的查询?
- 我的硬盘是SSD
- innodb_flush_log_at_trx_commit 的值 = 1
- 从上午 10 点到下午 2 点,写入/插入的数量大约为 1000/秒,在此期间之前和之后的请求要少得多。
【问题讨论】:
-
这个语句是否必要 (->orderBy('latest_update', 'desc'))?
-
你可以尝试索引
-
当您询问有关查询优化的问题时,请始终将
SHOW CREATE TABLE <tablename>的结果包含在查询中涉及的表中。不要让我们猜测您拥有的数据类型、索引和约束。帮助我们为您提供帮助! -
请提供生成的SQL。我们中的一些人在 SQL 中比在 许多 个前端包中更容易发现这些问题。
-
latest_update在哪个表中?它在优化方面产生了很大的不同。
标签: mysql laravel query-optimization