CREATE TABLE Konta ( IDKonta INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, StatusKonta enum('N','E','B','Z','O','R') NOT NULL DEFAULT 'N', NumerKonta varchar(32) NOT NULL DEFAULT '', IDZakresu INT(11) UNSIGNED NOT NULL DEFAULT '0', KtoWpisal INT(11) UNSIGNED NOT NULL DEFAULT '0', DataWpisania DATETIME PRIMARY KEY (IDKonta), KEY IDZakresu (IDZakresu), KEY KtoWpisal (KtoWpisal), KEY DataWpisania (DataWpisania) ) TYPE=MyISAM CREATE TABLE KontaKlientow ( IDKombinacji INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, IDKlienta INT(11) UNSIGNED NOT NULL DEFAULT '0', IDKonta INT(11) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (IDKombinacji), KEY IDKlienta (IDKlienta), KEY IDKonta (IDKonta) ) TYPE=MyISAM COMMENT='powiązania Klienci - konta' CREATE TABLE Klienci ( IDKlienta INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, Nazwisko VARCHAR(30), Imie VARCHAR(30), PRIMARY KEY (IDKlienta), KEY Nazwisko (Nazwisko) ) TYPE=MyISAM CREATE TABLE Uzytkownicy ( IDUzytkownika INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, ImieINazwisko VARCHAR(40), PRIMARY KEY (IDUzytkownika) ) TYPE=MyISAM CREATE TABLE Oddzialy ( IDOddzialu INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, Nazwa1 VARCHAR(30), Nazwa2 VARCHAR(30), PRIMARY KEY (IDOddzialu) ) TYPE=MyISAM CREATE TABLE Zakresy ( IDZakresu INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, Nazwa VARCHAR(30), PRIMARY KEY (IDZakresu) ) TYPE=MyISAM
Wpisuję zapytanie:
SELECT Konta.KtoWpisal, Konta.IDKonta, Konta.StatusKonta, Konta.NumerKonta, CONCAT_WS(' ', Klienci.Imie, Klienci.Nazwisko) AS NazwaKlienta, CONCAT_WS(' ', Oddzialy.Nazwa1, Odddzialy.Nazwa2) AS NazwaOddzialu, Oddzialy.IDOddzialu, Zakresy.IDZakresu FROM Konta, Klienci, Oddzialy, KontaKlientow, Uzytkownicy LEFT JOIN Zakresy ON Zakresy.IDZakresu = Konta.IDZakresu WHERE (DATE_FORMAT(Konta.DataWpisania,'%Y-%m-%d') BETWEEN '2004-09-01' AND '2004-09-30') AND Klienci.IDKlienta = KontaKlientow.IDKlienta AND KontaKlientow.IDKonta = Konta.IDKonta AND Uzytkownicy.IDUzytkownika = Konta.KtoWpisal AND Oddzialy.IDOddzialu = Uzytkownicy.IDOdddzialu
Zapytanie zwraca poprawną listę kont otwartych od w podanym zakresie dat.
Wszystko działa super, ale EXPLAIN dla tego zapytania zwraca coś takiego:
TABLE konta type ALL possible_keys PRIMARY,KtoWpisal KEY NULL key_len NULL ref NULL rows 370 Extra USING WHERE TABLE KontaKlientow type ALL possible_keys IDKlienta,IDRor KEY NULL key_len NULL ref NULL rows 50 Extra USING WHERE
Dlaczego NULL? Dlaczego ALL?? Przecież wszystkie niezbędne pola są poindeksowane!
Potem jest już ok:
TABLE klienci type eq_ref possible_keys PRIMARY KEY PRIMARY key_len 4 ref kontaklientow.IDKlienta rows 1 Extra TABLE Uzytkownicy type eq_ref possible_keys PRIMARY, IDOddzialu KEY PRIMARY key_len 4 ref Konta.KtoWpisal rows 1 Extra TABLE Odddzialy type eq_ref possible_keys PRIMARY, IDOddzialu KEY PRIMARY key_len 4 ref Uzytkownicy.IDOddzialu rows 1 Extra TABLE Zakresy type eq_ref possible_keys PRIMARY, IDZakresu KEY PRIMARY key_len 4 ref Konta.IDZakresu rows 1 Extra USING INDEX
Pomóżcie - co należy zrobić, żeby aparat MySQL nie skanował całych dwóch pierwszych tabeli?
Pozdrawiam