【问题标题】:Reduce execution time of query减少查询的执行时间
【发布时间】:2014-01-29 09:22:57
【问题描述】:

我想减少mysql中查询所花费的时间。

一共有三张表说

  1. 大约 60 万行,
  2. B ~2K 行,
  3. C ~100K 行

每列有 2 列。

  1. A 有一列用于聚合,另一列用于连接表 B。
  2. B 有一列与 A 连接,另一列与 C 连接
  3. 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


【解决方案1】:

试试这个:

SELECT
    sum(`revenue_facts`.`total_price`) AS `m0`
FROM 
    (`dim_products` LEFT JOIN `category_groups` ON `dim_products`.`product_category_group_sk` =  `category_groups`.`product_category_group_sk`)
    LEFT JOIN `revenue_facts` ON `dim_products`.`product_sk` = `revenue_facts`.`product_sk`
GROUP BY `category_groups`.`category_name`;

另外,正如阿卜杜勒所说:

“发布您的表结构并解释计划”

【讨论】:

  • 应该是INNER join。
  • 使用 join 关键字是否比使用 where 条件更快?
猜你喜欢
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多