-1

简单查询需要大约 630 秒才能执行全表扫描。请帮我重写查询并建议我是否需要添加任何索引。

询问:

mysql> explain SELECT count(DISTINCT(tab1.idnum)) as totalresults FROM (`tab1`) LEFT JOIN `tab2` ON tab2.idnum = tab1.col1id WHERE tab1.userid = '165258' AND `result` = 'correct' AND tab2.department = 'DEPT1' AND tab2.book = 2096 AND `quarantined` = 0;

解释计划:

+----+-------------+--------------+--------+------------------------------------+---------+---------+---------------------------+-------+-------------+
| id | select_type | table        | type   | possible_keys                      | key     | key_len | ref                       | rows  | Extra       |
+----+-------------+--------------+--------+------------------------------------+---------+---------+---------------------------+-------+-------------+
|  1 | SIMPLE      | tab1 | ref    | userid,col1id,result,userid_status | userid  | 4       | const                     | 14720 | Using where |
|  1 | SIMPLE      | tab2 | eq_ref | PRIMARY                            | PRIMARY | 4       | comp1.tab1.col1id |     1 | Using where |
+----+-------------+--------------+--------+------------------------------------+---------+---------+---------------------------+-------+-------------+
2 rows in set (0.00 sec)

表结构:

mysql> show create table tab1\G
*************************** 1. row ***************************
       Table: tab1
Create Table: CREATE TABLE `tab1` (
  `idnum` int(11) NOT NULL AUTO_INCREMENT,
  `questid` int(11) NOT NULL DEFAULT '0',
  `userid` int(11) NOT NULL DEFAULT '0',
  `col1id` int(11) NOT NULL DEFAULT '0',
  `result` enum('correct','incorrect') NOT NULL DEFAULT 'def1',
  `answergiven` varchar(35) NOT NULL DEFAULT '0',
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `status` enum('calibrating','normal') NOT NULL DEFAULT 'def2',
  `quarantined` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`idnum`),
  KEY `questid` (`questid`),
  KEY `userid` (`userid`),
  KEY `col1id` (`col1id`),
  KEY `result` (`result`),
  KEY `userid_status` (`userid`,`status`),
  KEY `questid_status` (`questid`,`status`),
  KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=143018786 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> show create table tab2\G
*************************** 1. row ***************************
       Table: tab2
Create Table: CREATE TABLE `tab2` (
  `idnum` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(11) NOT NULL DEFAULT '0',
  `timestarted` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `timefinished` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `questionlist` mediumtext NOT NULL,
  `topics` mediumtext NOT NULL,
  `totalnum` int(11) NOT NULL DEFAULT '0',
  `completednum` int(11) NOT NULL DEFAULT '0',
  `assignment` int(11) NOT NULL DEFAULT '0',
  `department` varchar(255) NOT NULL DEFAULT '',
  `book` int(11) NOT NULL DEFAULT '0',
  `cqs` mediumtext NOT NULL,
  `metatype` varchar(25) DEFAULT 'topic',
  PRIMARY KEY (`idnum`),
  KEY `userid` (`userid`),
  KEY `assignment` (`assignment`)
) ENGINE=InnoDB AUTO_INCREMENT=13547403 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
4

3 回答 3

1

您需要一个多列索引,即。同时跨越 tab1 中的 userid 和 col1id 的一个。尝试:

create index idx_usr_col1 on tab1(userid,col1id)
于 2013-03-20T04:31:45.767 回答
0

尝试为 MySQL 添加多列索引以供使用:

ALTER TABLE `tab2` ADD INDEX idx_col1id_userid_result_quarantined (`col1id`, `userid`, `result`, `quarantined`);

ALTER TABLE `tab1` ADD INDEX idx_department_book (`department`, `book`);
于 2013-10-30T05:56:00.600 回答
0

尝试这个:

SELECT count(distinct result.idnum)) as totalresults FROM `tab1` as result
inner join (select distinct idnum from `tab2` where department = 'DEPT1' and book = 2096 ) as col11 ON col11.idnum = result.col1id
 WHERE result.userid = '165258' AND `result` = 'correct'  AND `quarantined` = 0;
于 2013-03-20T07:51:06.007 回答