-1

クエリに時間がかかりすぎています。このクエリは、Web アプリケーションから取得されます。それは私たちのパフォーマンスに影響を与えていました.誰かがそれを書き直し、あなたの貴重な提案を私と共有するのを手伝ってください.

Explain Plan を使用したクエリ:

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フィドルを作成してみてください。そして、私の提案は、クエリを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

注:速度を上げるには、インデックス作成、テーブルに存在する行数、およびクエリの結果を制限することを確認してください。

EDIT2:

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 に答える