我在mysql查询中使用Join时出错了 - 解释结果也发布了

use*_*214 7 mysql join explain

我有这个查询,只需要3.5秒来获取2条记录.然而,推荐书中有超过10万行,用户为13k,课程为850,考试为2.

SELECT t.*, u.name, f.feedback
FROM testmonials t
INNER JOIN user u ON u.id = t.userid
INNER JOIN courses co ON co.id = t.courseid
LEFT JOIN exam ex ON ex.id = t.exam_id
WHERE t.status = 4
AND t.verfication_required = 'Y'
AND t.verfication_completed = 'N'
ORDER BY t.submissiondate DESC
Run Code Online (Sandbox Code Playgroud)

.解释结果:.

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  co  ALL     PRIMARY     NULL    NULL    NULL    850     Using temporary; Using filesort
1   SIMPLE  t   ref     CID,nuk_tran_user   CID     4   kms.co.id   8   Using where
1   SIMPLE  u   eq_ref  PRIMARY     PRIMARY     4   kms.t.userid    1   Using where
1   SIMPLE  ex  eq_ref  PRIMARY     PRIMARY     3   kms.t.eval_id   1   
Run Code Online (Sandbox Code Playgroud)

如果我删除courses表连接,那么查询会很快返回结果.我无法弄清楚为什么这个查询必须选择所有的课程行,即850?

我有什么想法我做错了吗?

编辑:我在courseid上有一个索引,在推荐表中有一个userid,这些是各自表的主键.

编辑2

我刚刚从推荐表中删除了courseid索引(只是为了测试),有趣的是查询返回的结果是0.22秒!!! 其他所有与上面相同的内容只删除了这个索引.

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  t   ALL     nuk_tran_user   NULL    NULL    NULL    130696  Using where; Using filesort
1   SIMPLE  u   eq_ref  PRIMARY     PRIMARY     4   kms.t.userid    1   Using where
1   SIMPLE  co  eq_ref  PRIMARY     PRIMARY     4   kms.t.courseid  1   
1   SIMPLE  ex  eq_ref  PRIMARY     PRIMARY     3   kms.t.exam_id   1   
Run Code Online (Sandbox Code Playgroud)

编辑3

编辑3

CREATE TABLE IF NOT EXISTS `courses` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `duration` varchar(100) NOT NULL DEFAULT '',
  `objectives` text NOT NULL,
  `updated_at` datetime DEFAULT NULL,
  `updated_by` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=851 ;


Testimonials


CREATE TABLE IF NOT EXISTS `testimonials` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `feedback` text NOT NULL,  
  `userid` int(10) unsigned NOT NULL DEFAULT '0',
  `courseid` int(10) unsigned NOT NULL DEFAULT '0',
  `eventid` int(10) unsigned NOT NULL DEFAULT '0',
  `emr_date` datetime DEFAULT NULL,
  `exam_required` enum('Y','N') NOT NULL DEFAULT 'N',
  `exam_id` smallint(5) unsigned NOT NULL DEFAULT '0',
  `emr_completed` enum('Y','N') NOT NULL DEFAULT 'N',
  PRIMARY KEY (`id`),
  KEY `event` (`eventid`),
  KEY `nuk_tran_user` (`userid`),
  KEY `emr_date` (`emr_date`),
  KEY `courseid` (`courseid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=134691 ;
Run Code Online (Sandbox Code Playgroud)

..这是最新的Explain查询结果...

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  t   ALL     nuk_tran_user,courseid  NULL    NULL    NULL    130696  Using where; Using filesort
1   SIMPLE  u   eq_ref  PRIMARY     PRIMARY     4   kms.t.userid    1   Using where
1   SIMPLE  co  eq_ref  PRIMARY     PRIMARY     4   kms.t.courseid  1   
1   SIMPLE  ex  eq_ref  PRIMARY     PRIMARY     3   kms.t.exam_id   1   
Run Code Online (Sandbox Code Playgroud)

Thi*_*nne 0

您可以尝试以下查询而不是原始查询:

SELECT t.*, u.name, f.feedback
FROM testmonials t
INNER JOIN user u ON u.id = t.userid
LEFT JOIN exam ex ON ex.id = t.exam_id
WHERE t.status = 4
AND t.verfication_required = 'Y'
AND t.verfication_completed = 'N'
AND t.courseid in ( SELECT co.id FROM courses co)
ORDER BY t.submissiondate DESC
Run Code Online (Sandbox Code Playgroud)

您需要从课程表中选择列吗?