1
  1. 查询大约需要 5 分钟到 20 分钟才能执行。
  2. 因此,我们遇到了负载峰值。
  3. 请帮我重写查询。
  4. 还帮助我提高查询的性能。

询问:

SELECT DATE(create_time) as createDate, count(url_id) 
  FROM t_notification 
 WHERE domain_id = 185 
   AND type = 12 
   AND create_time >= '2012-12-15' 
GROUP BY createDate

解释

explain select DATE(create_time) as createDate, count(url_id) from t_notification where domain_id = 185 and type = 12 and create_time >= '2012-12-15' group by createDate;
    +----+-------------+----------------+------+---------------------------------+----------+---------+-------+---------+----------------------------------------------+
    | id | select_type | table          | type | possible_keys                   | key      | key_len | ref   | rows    | Extra                                        |
    +----+-------------+----------------+------+---------------------------------+----------+---------+-------+---------+----------------------------------------------+
    |  1 | SIMPLE      | t_notification | ref  | FK_notification_domain,idx_test | idx_test | 5       | const | 9189516 | Using where; Using temporary; Using filesort |
    +----+-------------+----------------+------+---------------------------------+----------+---------+-------+---------+----------------------------------------------+
    1 row in set (0.29 sec)

mysql> show create table t_notification\G
*************************** 1. row ***************************
       Table: t_notification
Create Table: CREATE TABLE `t_notification` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` int(11) DEFAULT NULL,
  `content` varchar(512) DEFAULT NULL,
  `create_time` date DEFAULT NULL,
  `domain_id` int(11) DEFAULT NULL,
  `url_id` int(11) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  `targetrul_partnerurl_id` int(11) DEFAULT NULL,
  `week_entrances` int(11) DEFAULT NULL COMMENT 'for keyword and target_url',
  PRIMARY KEY (`id`),
  KEY `url_id` (`url_id`),
  KEY `targetrul_partnerurl_id` (`targetrul_partnerurl_id`),
  KEY `FK_notification_domain` (`domain_id`,`id`),
  KEY `idx_test` (`domain_id`,`status`,`type`,`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=50747991 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
4

2 回答 2

2

来自MySQl 文档

假设您发出以下 SELECT 语句:mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

如果 col1 和 col2 上存在多列索引,则可以直接获取相应的行。如果 col1 和 col2 上存在单独的单列索引,优化器将尝试使用索引合并优化(请参阅第 8.3.1.4 节,“索引合并优化”),或者通过确定哪个索引找到更少的索引来尝试找到最严格的索引行并使用该索引来获取行。

如果表有一个多列索引,优化器可以使用索引的任何最左边的前缀来查找行。例如,如果您在 (col1, col2, col3) 上有一个三列索引,则您在 (col1)、(col1, col2) 和 (col1, col2, col3) 上有索引搜索功能。

您没有关于 type 或 create_time 的可用索引。从键 idx_test 中删除状态或在 (type, create_time) 或 type 和 create_time 上分别创建新索引。

于 2013-01-17T06:43:57.560 回答
0

考虑在domain_idtype列上创建复合索引,因为它们直接在 where 子句中使用。它肯定会提高您的查询的性能。

于 2013-01-17T06:43:56.580 回答