2013-03-25 5 views
7

Mam to zapytanie, które trwa około 3,5 sekundy, aby pobrać 2 rekordy. Jednak w opiniach jest ponad 100 tys. Wierszy, 13 tys. Użytkowników, 850 na kursach i 2 na egzaminach.Gdzie popełniam błąd przy użyciu funkcji Dołącz w zapytaniu mysql - Wyjaśnij wynik również opublikowany

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 

. Wyjaśnienie wyniku:.

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 

Jeśli usunąć tabelę courses przyłączyć następnie kwerenda zwraca wynik dość szybki. Nie mogę zrozumieć, dlaczego to zapytanie musi wybrać wszystkie wiersze kursów, np. 850?

Jakieś pomysły, co robię źle?

Edytuj: Mam indeks courseid, userid w tabeli referencji i są to klucze podstawowe odpowiednich tabel.

EDIT 2

właśnie usunięto indeks courseid z tabeli referencje (tylko test) i co ciekawe zapytanie wynik zwracany w 0,22 sekundy !!! ?? Wszystko inne, tak jak wyżej, usunęło tylko ten indeks.

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 ; 

.. Jest to najnowsza Wyjaśnij wynik kwerendy teraz ...

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

czy masz indeks na 'courses.ID'? –

+0

tak ma indeks w tabeli referencji i jest kluczem podstawowym tabeli kursów. – user1421214

+0

Ponieważ nie wygląda na to, że masz ... –

Odpowiedz

0

Mógłbyś dać spróbować następujących zapytanie zamiast oryginału:

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 

Czy chcesz wybrać kolumny z tabeli kursów?

1

Wykonanie ZAMÓWIENIA, które nie ma odpowiedniego indeksu, który może być wykorzystany, powoduje problemy z opóźnieniem. Nawet jeśli nie odpowiada to konkretnie twojemu problemowi z tabeli kursów.

Twoje pierwotne zapytanie wygląda NAJBARDZIEJ OK, ale odwołujesz się do "f.feedback" i nie ma w zapytaniu aliasu "f". Odwołujesz się także do "verification_required" i "verification_completed", ale nie widzisz tych w strukturach tabeli, ale DO find "exam_required" i "emr_completed".

Chciałbym jednak zmienić jedną rzecz. W tabeli referencje, zamiast poszczególnych indeksów kolumn, chciałbym dodać jeszcze jeden z wielu kolumn zarówno wziąć korzyść swojej wielu kryteriów zapytania i zlecenia przez

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

ale pojawia się zapytanie odnosi się do kolumn niewymienionych w Twojej struktury tabeli, ale zamiast niej może być

KEY StatVerifySubmit (status, exam_required, emr_completed, emr_Date) 
Powiązane problemy