【发布时间】:2014-01-29 09:22:57
【问题描述】:
我想减少mysql中查询所花费的时间。
一共有三张表说
- 大约 60 万行,
- B ~2K 行,
- C ~100K 行
每列有 2 列。
- A 有一列用于聚合,另一列用于连接表 B。
- B 有一列与 A 连接,另一列与 C 连接
- C 有一列与 B 连接,另一列作为分组依据。
应该有什么索引计划来减少运行时间。截至目前,它正在使用临时表,然后是文件排序。有什么办法可以避免临时表。
示例查询:
SELECT
sum(`revenue_facts`.`total_price`) AS `m0`
FROM
`category_groups` AS `category_groups`,
`revenue_facts` AS `revenue_facts`,
`dim_products` AS `dim_products`
WHERE
`dim_products`.`product_category_group_sk` = `category_groups`.`product_category_group_sk` AND
`revenue_facts`.`product_sk` = `dim_products`.`product_sk`
GROUP BY `category_groups`.`category_name`;
我已经对按列分组和加入的列有索引。
我的查询目前需要 *6 分钟*s。我想减少花费的时间。表结构为
表 A:
CREATE TABLE `revenue_facts` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`product_sk` bigint(20) unsigned NOT NULL,
`total_price` decimal(12,2) NOT NULL,
PRIMARY KEY (`id`),
KEY `product_sk` (`product_sk`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表 B:
CREATE TABLE `dim_products` (
`product_sk` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`product_category_group_sk` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`product_sk`),
KEY `product_id` (`product_id`),
KEY (`product_sk`) (`product_sk`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表 C:
CREATE TABLE `category_groups` (
`product_category_group_sk` bigint(20) unsigned NOT NULL,
`category_sk` bigint(20) unsigned NOT NULL,
`category_name` varchar(255) NOT NULL,
PRIMARY KEY (`product_category_group_sk`,`category_sk`),
KEY `category_sk` (`category_sk`),
KEY `product_category_group_sk` (`product_category_group_sk`
KEY `category_sk` (`category_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
使用的执行计划是:
1 SIMPLE dim_products index PRIMARY,product_category_group_index product_category_group_index 8 NULL 651264 Using index; Using temporary; Using filesort
1 SIMPLE category_groups ref PRIMARY,category_sk,product_category_group_sk,category_name product_category_group_sk 8 etl_testing.dim_products.product_category_group_sk 4 Using index
1 SIMPLE revenue_facts ref product_sk product_sk 8 etl_testing..dim_products.product_sk 5 NULL
【问题讨论】:
-
发布您的表格结构并解释计划
-
您的索引似乎很好。您有什么问题?您的查询到底有多慢?
-
如果您像这样使用 join 和 group by,则无法逃避临时和文件排序。添加更多关于你到底想要做什么的信息。使用 FROM table_name AS table_name 只会使查询变得丑陋。如果您真的说出 A、B、C 是什么表,那将会很有帮助,这样我们就不必在哪里寻找那么长的时间来推断谁是谁。
-
添加了表结构和使用的执行计划。查询耗时超过 6 分钟。
标签: mysql sql performance innodb