-1

查询花费了太多时间。此查询来自网络应用程序。它影响了我们的表现。任何人请帮我重写它并与我分享您的宝贵建议。

使用解释计划查询:

mysql> explain SELECT DISTINCT(tab2.idnum) FROM (`tab2`) JOIN `tab1` ON tab1.question = tab2.idnum WHERE `department` = 'Biology' AND tab2.status != 'active' AND tab2.status != 'retired' AND (tab2.instructor = 164604 OR tab2.instructor = 194703) AND tab1.topic IN (SELECT `topic` FROM (`tab5`) JOIN `tab4` ON tab4.chapter = tab5.id WHERE `book` = 1000) AND tab2.idnum NOT IN (SELECT `question` FROM (`tab3`) WHERE `book` = 1000 AND `isPR` = 1) AND `questiontype` IN ('mult') limit 2;
+----+--------------------+-----------------+-----------------+------------------+---------+---------+-------------------------------+--------+-------------------------------------------+
| id | select_type        | table           | type            | possible_keys    | key     | key_len | ref                           | rows   | Extra                                     |
+----+--------------------+-----------------+-----------------+------------------+---------+---------+-------------------------------+--------+-------------------------------------------+
|  1 | PRIMARY            | tab1  | index           | question         | tq      | 8       | NULL                          | 149899 | Using where; Using index; Using temporary |
|  1 | PRIMARY            | tab2  | eq_ref          | PRIMARY          | PRIMARY | 4       | comp1.tab1.question |      1 | Using where                               |
|  3 | DEPENDENT SUBQUERY | tab3 | unique_subquery | qb,question,book | qb      | 8       | func,const                    |      1 | Using where                               |
|  2 | DEPENDENT SUBQUERY | tab4  | ref             | chapter,topic    | topic   | 4       | func                          |      1 |                                           |
|  2 | DEPENDENT SUBQUERY | tab5     | eq_ref          | PRIMARY          | PRIMARY | 4       | comp1.tab4.chapter  |      1 | Using where                               |
+----+--------------------+-----------------+-----------------+------------------+---------+---------+-------------------------------+--------+-------------------------------------------+
5 rows in set (0.00 sec)

表结构:

mysql> show create table tab5\G
*************************** 1. row ***************************
       Table: tab5
Create Table: CREATE TABLE `tab5` (
  `name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
  `descrip` mediumtext NOT NULL,
  `category` varchar(255) NOT NULL DEFAULT '',
  `order` int(11) NOT NULL DEFAULT '0',
  `department` varchar(255) NOT NULL DEFAULT '',
  `book` int(11) NOT NULL DEFAULT '0',
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `is_trial` tinyint(1) NOT NULL DEFAULT '0',
  `is_live` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6305 DEFAULT CHARSET=latin1

mysql> show create table tab4\G
*************************** 1. row ***************************
       Table: tab4
Create Table: CREATE TABLE `tab4` (
  `chapter` int(11) NOT NULL DEFAULT '0',
  `topic` int(11) NOT NULL DEFAULT '0',
  KEY `chapter` (`chapter`),
  KEY `topic` (`topic`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> show create table tab3\G
*************************** 1. row ***************************
       Table: tab3
Create Table: CREATE TABLE `tab3` (
  `question` int(11) NOT NULL,
  `book` int(11) NOT NULL,
  `isPR` tinyint(1) unsigned NOT NULL DEFAULT '0',
  UNIQUE KEY `qb` (`question`,`book`),
  KEY `question` (`question`),
  KEY `book` (`book`)
) ENGINE=InnoDB 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,
  `questiontype` enum('mult','CM','GO','FIB','AUD','HS','DD') NOT NULL DEFAULT 'def1',
  `question` mediumtext NOT NULL,
  `difficulty` int(3) DEFAULT '0',
  `createdby` int(11) NOT NULL DEFAULT '0',
  `createdwhen` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `status` enum('active','calibrating','onhold','retired') NOT NULL DEFAULT 'def1',
  `parent` int(11) NOT NULL DEFAULT '0',
  `child` int(11) NOT NULL DEFAULT '0',
  `family` int(11) NOT NULL DEFAULT '0',
  `department` varchar(255) NOT NULL DEFAULT '',
  `notes` text NOT NULL,
  `instructor` int(11) NOT NULL DEFAULT '0',
  `nmfilter` enum('everyone','majors only','undetermined') NOT NULL DEFAULT 'def1',
  `PR` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`idnum`),
  KEY `family` (`family`)
) ENGINE=InnoDB AUTO_INCREMENT=186724 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> show create table tab1\G
*************************** 1. row ***************************
       Table: tab1
Create Table: CREATE TABLE `tab1` (
  `question` int(11) NOT NULL DEFAULT '0',
  `topic` int(11) NOT NULL DEFAULT '0',
  KEY `question` (`question`),
  KEY `topic` (`topic`),
  KEY `tq` (`topic`,`question`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
4

1 回答 1

2

这是一个复杂的分析。尝试创建 sql fiddle 以更好地理解您的问题。我的建议是,尝试仅使用 JOIN 重写您的查询(删除嵌套查询)并尝试以下查询,

SELECT tab2.idnum
FROM (`tab2`) INNER JOIN `tab1` ON tab1.question = tab2.idnum INNER JOIN `tab3` ON tab2.idnum != tab3.question INNER JOIN `tab5` ON tab1.topic = tab5.topics
INNER JOIN `tab4` ON tab4.chapter = tab5.id 
WHERE 
tab5.department = 'Biology' AND tab2.status != 'active' AND tab2.status != 'retired' AND 
(tab2.instructor = 164604 OR tab2.instructor = 194703) 
AND tab5.book = 1000 AND tab3.book =  1000 AND tab3.isPR = 1
AND tab2.questiontype IN ('mult')

注意:由于我不确定您要达到的目标,因此我删除了 DISTINCT、LIMIT 之类的一些内容。但我希望这会让你知道如何处理这个问题。

要给出更合适的答案,只需使用表格和数据更新您的帖子或创建 sqlfiddle 并解释您试图从这些表格中实现的目标以及您如何将它们关联起来。

编辑:

SELECT tab2.idnum
FROM (`tab2`) INNER JOIN `tab1` ON tab1.question = tab2.idnum AND (tab2.status != 'active' AND tab2.status != 'retired' AND (tab2.instructor = 164604 OR tab2.instructor = 194703) AND tab2.questiontype IN ('mult')) 
INNER JOIN `tab3` ON tab2.idnum != tab3.question AND tab3.book =  1000 AND tab3.isPR = 1
INNER JOIN `tab5` ON tab1.topic = tab5.topics AND tab5.department = 'Biology' AND tab5.book = 1000
INNER JOIN `tab4` ON tab4.chapter = tab5.id

注意:为了提高速度,请确保您的索引、表中存在多少行并限制查询结果。

编辑2:

SELECT tab2.idnum
FROM `tab2` INNER JOIN `tab1` ON tab1.question = tab2.idnum AND (tab2.status != 'active' AND tab2.status != 'retired' AND (tab2.instructor = 164604 OR tab2.instructor = 194703) AND tab2.questiontype IN ('mult')) 
INNER JOIN `tab3` ON tab2.idnum != tab3.question AND tab3.book =  1000 AND tab3.isPR = 1
INNER JOIN `tab5` ON tab5.department = 'Biology' AND tab5.book = 1000
INNER JOIN `tab4` ON tab4.chapter = tab5.id
WHERE tab1.topic = tab4.topic
于 2013-03-20T11:25:17.390 回答