【发布时间】:2020-03-03 23:31:30
【问题描述】:
我在定价表上创建了分区。下面是alter语句。
ALTER TABLE `price_tbl`
PARTITION BY HASH(man_code)
PARTITIONS 87;
一个分区由 435510 条记录组成。 price_tbl 中的总记录为 600 万。
EXPLAIN 查询只显示一个部分用于查询。查询仍然需要 3-4 秒 才能执行。以下是查询
EXPLAIN SELECT vrimg.image_cap_id,vm.man_name,vr.range_code,vr.range_name,vr.range_url, MIN(`finance_rental`) AS from_price, vd.der_id AS vehicle_id FROM `range_tbl` vr
LEFT JOIN `image_tbl` vrimg ON vr.man_code = vrimg.man_code AND vr.type_id = vrimg.type_id AND vr.range_code = vrimg.range_code
LEFT JOIN `manufacturer_tbl` vm ON vr.man_code = vm.man_code AND vr.type_id = vm.type_id
LEFT JOIN `derivative_tbl` vd ON vd.man_code=vm.man_code AND vd.type_id = vr.type_id AND vd.range_code=vr.range_code
LEFT JOIN `price_tbl` vp ON vp.vehicle_id = vd.der_id AND vd.type_id = vp.type_id AND vp.product_type_id=1 AND vp.maintenance_flag='N' AND vp.man_code=164
AND vp.initial_rentals_id =(SELECT rental_id FROM `rentals_tbl` WHERE rental_months='9')
AND vp.annual_mileage_id =(SELECT annual_mileage_id FROM `mileage_tbl` WHERE annual_mileage='8000')
WHERE vr.type_id = 1 AND vm.man_url = 'audi' AND vd.type_id IS NOT NULL GROUP BY vd.der_id
解释的结果。
没有分区的相同查询需要 3-4 秒。 分区查询需要 2-3 秒。
我们如何提高查询性能,因为它太慢了。
附加创建表结构。
- 价格表 - 包含 600 万条记录
CREATE TABLE `price_tbl` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`lender_id` bigint(20) DEFAULT NULL,
`type_id` bigint(20) NOT NULL,
`man_code` bigint(20) NOT NULL,
`vehicle_id` bigint(20) DEFAULT NULL,
`product_type_id` bigint(20) DEFAULT NULL,
`initial_rentals_id` bigint(20) DEFAULT NULL,
`term_id` bigint(20) DEFAULT NULL,
`annual_mileage_id` bigint(20) DEFAULT NULL,
`ref` varchar(255) DEFAULT NULL,
`maintenance_flag` enum('Y','N') DEFAULT NULL,
`finance_rental` decimal(20,2) DEFAULT NULL,
`monthly_rental` decimal(20,2) DEFAULT NULL,
`maintenance_payment` decimal(20,2) DEFAULT NULL,
`initial_payment` decimal(20,2) DEFAULT NULL,
`doc_fee` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`,`type_id`,`man_code`),
KEY `type_id` (`type_id`),
KEY `vehicle_id` (`vehicle_id`),
KEY `term_id` (`term_id`),
KEY `product_type_id` (`product_type_id`),
KEY `finance_rental` (`finance_rental`),
KEY `type_id_2` (`type_id`,`vehicle_id`),
KEY `maintenanace_idx` (`maintenance_flag`),
KEY `lender_idx` (`lender_id`),
KEY `initial_idx` (`initial_rentals_id`),
KEY `man_code_idx` (`man_code`)
) ENGINE=InnoDB AUTO_INCREMENT=5830708 DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (man_code)
PARTITIONS 87 */
- 派生表 - 这包含 18k 条记录。
CREATE TABLE `derivative_tbl` (
`type_id` bigint(20) DEFAULT NULL,
`der_cap_code` varchar(20) DEFAULT NULL,
`der_id` bigint(20) DEFAULT NULL,
`body_style_id` bigint(20) DEFAULT NULL,
`fuel_type_id` bigint(20) DEFAULT NULL,
`trans_id` bigint(20) DEFAULT NULL,
`man_code` bigint(20) DEFAULT NULL,
`range_code` bigint(20) DEFAULT NULL,
`model_code` bigint(20) DEFAULT NULL,
`der_name` varchar(255) DEFAULT NULL,
`der_url` varchar(255) DEFAULT NULL,
`der_intro_year` date DEFAULT NULL,
`der_disc_year` date DEFAULT NULL,
`der_last_spec_date` date DEFAULT NULL,
KEY `der_id` (`der_id`),
KEY `type_id` (`type_id`),
KEY `man_code` (`man_code`),
KEY `range_code` (`range_code`),
KEY `model_code` (`model_code`),
KEY `body_idx` (`body_style_id`),
KEY `capcodeidx` (`der_cap_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
- 范围表 - 包含 1k 条记录
CREATE TABLE `range_tbl` (
`type_id` bigint(20) DEFAULT NULL,
`man_code` bigint(20) DEFAULT NULL,
`range_code` bigint(20) DEFAULT NULL,
`range_name` varchar(255) DEFAULT NULL,
`range_url` varchar(255) DEFAULT NULL,
KEY `range_code` (`range_code`),
KEY `type_id` (`type_id`),
KEY `man_code` (`man_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
【问题讨论】:
-
您应该更担心查询的正确性,因为这通常不是如何使用GROUP BY .. 启用 sql_mode ONLY_FULL_GROUP_BY 的 MySQL 5.7.5+ 可以信任此查询为那里支持检测功能依赖性,您在这里信任它.. .. 假设查询是功能依赖性的,我没有检查...
-
分区并不是提高性能(喷气机)的万能子弹,这可能会在未来发生变化,因为 MySQL 开发团队正在努力对 InnoDB 引擎的Parallel Query Execution 支持。还有另一篇文章MySQL 8.0.14: A Road to Parallel Query Execution is Wide Open! 确实表明它仍然非常有限,但这是一个正确的开始,我们等了很久吗?..
-
... 同样从查询和解释的角度来看,我很确定 SQL 重写是获得更好性能的最佳选择,因为优化器接缝以“错误”顺序访问表防止临时表和排序..
-
请参阅Why should I provide a Minimal Reproducible Example for a very simple SQL query? 以提供示例数据和预期结果,以便我们可以验证 SQL 重写。也请执行
SHOW VERSION(),因为 MySQL 优化器在主要 MySQL 版本之间可能非常不同。.跨度> -
附加信息请求。在 pastebin.com 上发布并分享链接。 RAM 大小,# 核心,MySQL 主机服务器上的任何 SSD 设备来自 SSH 登录根,文本结果:B) SHOW GLOBAL STATUS;至少 24 小时正常运行时间后 C) 显示全局变量; D) 显示完整的处理程序; E) 完整的 MySQLTuner 报告和可选的非常有用的信息,如果可用包括 - htop OR top OR mytop 用于大多数活动应用程序,ulimit -a 用于 linux/unix 限制列表,iostat -xm 5 3 用于按设备和核心/cpu 的 IOPS count,为服务器工作负载调优分析提供建议。
标签: mysql partitioning mysql-5.7