为什么此查询需要超过180秒才能运行?

时间:2020-02-03 10:49:02

标签: mysql

CREATE TABLE `tvnotif` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pingId` int(11) DEFAULT NULL,
  `token` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  `summary` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  `startTime` int(11) DEFAULT NULL,
  `endTime` int(11) DEFAULT NULL,
  `processed` int(1) DEFAULT '0',
  `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `processedIndex` (`processed`),
  KEY `summaryIndex` (`summary`),
  KEY `tokenIndex` (`token`)
) ENGINE=InnoDB AUTO_INCREMENT=18297898 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


CREATE TABLE `vv_us` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `athleteid` int(11) DEFAULT NULL,
  `token` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  `secret` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  `active` int(1) DEFAULT '1',
  `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `type` varchar(45) COLLATE utf8_bin DEFAULT 'mc',
  `step` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  `host` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  `server` mediumblob,
  `tempcreds` mediumblob,
  PRIMARY KEY (`id`),
  KEY `activeIndex` (`active`),
  KEY `typeIndex` (`type`)
) ENGINE=InnoDB AUTO_INCREMENT=33888 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

我正在运行一个查询,该查询主要基于表tvnotif,其中至少有200万行数据,所有其他表的查询量都较少。在查询需要20分钟才能运行,而现在却需要160秒的时间之前,我为这些表添加了索引。

EXPLAIN SELECT tvu.secret,COALESCE(php_timezone,"America/Los_Angeles") AS userTz,tn.*,tvu.athleteid,tvu.type FROM tvnotif AS tn 
            LEFT JOIN vv_us AS tvu ON  tvu.token = tn.token
            LEFT JOIN tbl_ath_pro AS tap ON tap.athleteid = tvu.athleteid
            LEFT JOIN timezones AS tz ON tz.tz_id = tap.tz_id
            WHERE tvu.active = 1 AND tn.summary = 'dailies' AND tn.processed = 0
            LIMIT 300

enter image description here

1 个答案:

答案 0 :(得分:2)

问题可能出在您的索引上...您分别在每个字段上都有索引。您需要的是将所有3个部分的复合索引作为单个索引。没有,就不能选择最好的一个,因为where子句包含3个部分。

在(已处理,摘要,令牌)上建立一个单一索引

通过这种方式,查询可以直接跳到已处理的记录,直接跳到汇总值,然后获取这些记录并完成。

此外,您的VV_US表应该在(令牌,活动)上具有索引,因此将在两个部件上优化连接。