2013-03-25 8 views
7

私はこのクエリを持っていますが、これは2レコードをフェッチするのに約3.5秒かかります。しかし、推薦状には100,000行以上があり、ユーザーは13k、コースは850件、試験は2件あります。mysqlクエリで結合を使用するのが間違っているところ - 結果の投稿も説明してください

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 

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 

coursesテーブル結合を削除すると、クエリは結果を非常に迅速に返します。私はなぜこのクエリがすべてのコース行、すなわち850を選択しなければならないのか分かりません。

私が間違っていることは何ですか?

編集: 私はcourseid、userimidの表をtestimonials表に持っています。これらはそれぞれの表の主キーです。

EDIT 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 

EDIT 3

EDIT 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 ; 

。これは、最新の説明クエリ結果である今...

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 
+1

あなたは 'courses.ID'のインデックスを持っていましたか? –

+0

はいそれは、功績表にインデックスを持ち、コーステーブルの主キーを持っています。 – user1421214

+0

あなたが持っているように見えないので... –

答えて

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 

コーステーブルから列を選択する必要がありますか?

1

利用可能な対応するインデックスを持たないORDER BYを実行すると、遅延の問題が発生することが知られています。これはもちろん、コーステーブルの問題には答えません。

元のクエリは大丈夫ですが、 "f.backback"を参照し、クエリに "f"エイリアスはありません。また、 "verification_required"と "verification_completed"を参照していますが、テーブル構造には表示されませんが、 "exam_required"と "emr_completed"があります。

ただし、私は1つのことを変更します。証言台では、代わりに、個々の列のインデックスを、私は

create table ... 
KEY StatVerifySubmit (status, verification_required, verification_completed, submissionDate) 

して複数の条件の照会および順序の両方を活用し、複数の列との1以上を追加しますが、あなたのクエリがに記載されていない列を参照している表示されますあなたのテーブル構造のリストは、代わりに

KEY StatVerifySubmit (status, exam_required, emr_completed, emr_Date) 
関連する問題