0

下面的查询大约需要 10 分钟到 1 小时才能执行。因此,我们经常遇到负载峰值。任何人都可以帮助以更优化的方式重写查询。

询问:

  select count(*) 
  from t_tab6 tab1 
  left join t_tab6_element_tab2 tab2 
     on tab2.tab6_id = tab1.id 
  left join t_tab3 tab3
    on tab1.create_tab3_id = tab3.id 
  left join t_tab4 tab4 
    on  tab2.element_id = tab4.id and tab2.element_type_id = 1 
  left join t_tab7 tab5 
    on  tab2.element_id = tab5.id and tab2.element_type_id = 2 
  where tab1.domain_id = 522

解释计划:

    +----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
    | id | select_type | table     | type   | possible_keys           | key                     | key_len | ref                        | rows   | Extra       |
    +----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
    |  1 | SIMPLE      | tab1       | ref    | domain_id_tab6_type_cd | domain_id_tab6_type_cd | 4       | const                      | 243430 |             |
    |  1 | SIMPLE      | tab2       | ref    | FK_tab6                | FK_tab6                | 4       | comp1.tab1.id             |      2 |             |
    |  1 | SIMPLE      | tab3      | eq_ref | PRIMARY                 | PRIMARY                 | 4       | comp1.tab1.create_tab3_id |      1 | Using index |
    |  1 | SIMPLE      | tab4   | ref    | id                      | id                      | 4       | comp1.tab2.element_id     |      1 | Using index |
    |  1 | SIMPLE      | tab5 | ref    | id                      | id                      | 4       | comp1.tab2.element_id     |      1 | Using index |
    +----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
    5 rows in set (0.45 sec)

表结构:

  mysql> show create table t_tab6_element_tab2\G
    *************************** 1. row ***************************
           Table: t_tab6_element_tab2
    Create Table: CREATE TABLE `t_tab6_element_tab2` (
      `id` int(255) NOT NULL AUTO_INCREMENT,
      `element_type_id` int(11) NOT NULL,
      `tab6_id` int(11) NOT NULL,
      `element_id` int(11) NOT NULL,
      `element_desc` varchar(500) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `FK_tab6` (`tab6_id`),
      KEY `element_type_id_element_id` (`element_type_id`,`element_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=45901159 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)

    mysql> show create table t_tab3\G
    *************************** 1. row ***************************
           Table: t_tab3
    Create Table: CREATE TABLE `t_tab3` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `password` varchar(255) DEFAULT NULL,
      `email` varchar(255) DEFAULT NULL,
      `is_admin` int(11) DEFAULT NULL,
      `phone` varchar(50) DEFAULT NULL,
      `company` varchar(255) DEFAULT NULL,
      `last_login` datetime DEFAULT NULL,
      `state` int(11) DEFAULT NULL,
      `validate_code` varchar(50) DEFAULT NULL,
      `has_login` smallint(6) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1304 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)


    mysql> show create table t_tab6\G
    *************************** 1. row ***************************
           Table: t_tab6
    Create Table: CREATE TABLE `t_tab6` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `create_tab3_id` int(11) DEFAULT NULL,
      `tab6_create_date` date DEFAULT NULL,
      `tab6_type_cd` int(11) NOT NULL,
      `tab6_desc` varchar(512) NOT NULL,
      `IsGlobaltab6` int(2) DEFAULT NULL,
      `tab6_start_date` datetime NOT NULL,
      `tab6_end_date` datetime NOT NULL,
      `job_id` int(11) DEFAULT NULL,
      `domain_id` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `tab6_tab3_FK` (`create_tab3_id`),
      KEY `domain_id_tab6_type_cd` (`domain_id`,`tab6_type_cd`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8586007 DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)

    mysql> show create table t_tab4\G
    *************************** 1. row ***************************
           Table: t_tab4
    Create Table: CREATE TABLE `t_tab4` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `tab4_name` varchar(255) DEFAULT NULL,
      `tab4_value` varchar(255) DEFAULT NULL,
      `type` int(11) DEFAULT NULL,
      `description` varchar(2000) DEFAULT NULL,
      `own_domain_id` int(11) DEFAULT NULL,
      `rank_check` int(11) DEFAULT NULL,
      `rank1` int(11) DEFAULT NULL,
      `rank2` int(11) DEFAULT NULL,
      `rank3` int(11) DEFAULT NULL,
      `yesterday_entrances` int(11) DEFAULT NULL,
      `week_entrances` int(11) DEFAULT NULL,
      `current_ctr` float(16,4) DEFAULT NULL,
      `monthly_search_volume` int(11) DEFAULT NULL,
      `avg_monthly_search_volume` int(11) DEFAULT NULL,
      `traffic_increase` int(11) DEFAULT NULL,
      `rank_improvement` int(11) DEFAULT NULL,
      `rank_update_date` date DEFAULT NULL,
      `top_rank_tab5_id` int(11) DEFAULT NULL,
      `frequency` int(10) DEFAULT '1',
      `score` float DEFAULT NULL,
      `create_date` datetime DEFAULT NULL,
      `bing_rank1` int(10) DEFAULT NULL,
      `bing_rank2` int(10) DEFAULT NULL,
      `yesterday_bing_entrances` int(11) DEFAULT NULL,
      `bing_rank_improvement` int(11) DEFAULT NULL,
      KEY `id` (`id`),
      KEY `tab4_name` (`tab4_name`),
      KEY `own_domain_id` (`own_domain_id`,`rank_check`),
      KEY `rank_check` (`rank_check`)
    ) ENGINE=InnoDB AUTO_INCREMENT=670267018 DEFAULT CHARSET=utf8
    /*!50100 PARTITION BY RANGE (`rank_check`)
    (PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
     PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB,
     PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB,
     PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
    1 row in set (0.00 sec)

    mysql> show create table t_tab7\G
    *************************** 1. row ***************************
           Table: t_tab7
    Create Table: CREATE TABLE `t_tab7` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `own_domain_id` int(11) DEFAULT NULL,
      `url` varchar(2000) NOT NULL,
      `create_date` datetime DEFAULT NULL,
      `friendly_name` varchar(255) DEFAULT NULL,
      `section_name_id` int(11) DEFAULT NULL,
      `type` int(11) DEFAULT NULL,
      `status` int(11) DEFAULT NULL,
      `week_entrances` int(11) DEFAULT NULL,
      `week_bounces` int(11) DEFAULT NULL,
      `canonical_url_id` int(11) DEFAULT NULL,
      KEY `id` (`id`),
      KEY `urlindex` (`url`(255)),
      KEY `own_domain_id_type_status` (`own_domain_id`,`type`,`status`),
      KEY `canonical_url_id` (`canonical_url_id`),
      KEY `type` (`type`,`status`)
    ) ENGINE=InnoDB AUTO_INCREMENT=237034388 DEFAULT CHARSET=utf8
    /*!50100 PARTITION BY RANGE (`type`)
    (PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
     PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB,
     PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB,
     PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
    1 row in set (0.01 sec)
4

2 回答 2

2

试试下面

select count(*) 
  from (Select id,create_tab3_id from tab6   where domain_id = 522) as  tab1 
  left join tab6_element_tab2 tab2 
     on tab2.tab1nt_id = tab1.id 
  left join t_tab3 tab3
    on tab1.create_tab3_id = tab3.id 
  left join t_tab4 tab4 
    on  tab2.element_id = tab4.id and tab2.element_type_id = 1 
  left join t_tab7 tab5 
    on  tab2.element_id = tab5.id and tab2.element_type_id = 2 

如果您仅使用 for count 并在 where 子句中添加域类型检查,请删除左连接 t_tab3 tab3

于 2013-03-07T10:37:40.020 回答
0

在您的条件中使用的列上定义一个索引:

create index t_tab6_domain_id_index on t_tab6(domain_id);

查询本身似乎很好。

于 2013-01-17T06:59:38.177 回答