MySQL JOIN időköltsége (Hogyan ésszerűbb lekérdezni?)
Üdv mindenkinek!
Alapvetőnek tűnik, de nem sikerült választ találnom rá. A MySQL "EXPLAIN EXTENDED SELECT..." eredményét nem igazán sikerült értelmeznem.
Adott egy MySQLadattár:A 3,000 tételből meg kell jelenítenem 20-at egy lapon. Mi a gyorsabb megoldás, mi használ kevesebb erőforrást?
1. lehetőség2. lehetőségElőre is köszönöm a segítséget.
■ Alapvetőnek tűnik, de nem sikerült választ találnom rá. A MySQL "EXPLAIN EXTENDED SELECT..." eredményét nem igazán sikerült értelmeznem.
Adott egy MySQLadattár:
SET NAMES utf8;
CREATE TABLE `zokni` (
`SORSZAM` tinyint(4) unsigned NOT NULL default '0',
`FAJTAKULCS` tinyint(2) unsigned NOT NULL default '0',
`SZINKULCS` tinyint(2) unsigned NOT NULL default '0',
`LEIRAS_1` varchar(45) COLLATE utf8_general_ci NOT NULL COMMENT 'ide jöhet pl. a gyártó',
`LEIRAS_2` text COLLATE utf8_general_ci NOT NULL COMMENT 'ecsetelgetem, milyen szép is ez',
`AR` tinyint(4) unsigned NOT NULL default '0' COMMENT 'az ár forintban',
PRIMARY KEY (`SORSZAM`)
KEY `FAJTAKULCS` (`FAJTAKULCS`),
KEY `SZINKULCS` (`SZINKULCS`),
) ENGINE=MyISAM COLLATE=utf8_general_ci;
INSERT INTO `zokni` VALUES (1, 1, 2, 'Egyesült Zokniművek Rt.', 'csodás benne a séta', 800);
INSERT INTO `zokni` VALUES (2, 2, 1, 'Alsókukutyinfalvi Zoknikunyhó', 'szinte ingyen', 100);
# ... stb. (3,000 tétel)
CREATE TABLE `fajta` (
`FAJTAKULCS` tinyint(2) unsigned NOT NULL default '0',
`FAJTA` varchar(128) COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`FAJTAKULCS`)
) ENGINE=MyISAM COLLATE=utf8_general_ci;
INSERT INTO `fajta` VALUES (1, 'rövid szellős tavaszi');
INSERT INTO `fajta` VALUES (2, 'hosszú vastag téli');
# ... stb.
CREATE TABLE `szin` (
`SZINKULCS` tinyint(2) unsigned NOT NULL default '0',
`SZIN` varchar(128) COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`SZINKULCS`)
) ENGINE=MyISAM COLLATE=utf8_general_ci;
INSERT INTO `szin` VALUES (1, 'piros, zöld pöttyökkel');
INSERT INTO `szin` VALUES (2, 'sárga, szürke csíkokkal');
# ... stb.
1. lehetőség
<?php
$eredmény_zokni=mysql_query("
SELECT zokni.*,
fajta.FAJTA,
szin.SZIN
FROM zokni LEFT JOIN (fajta, szin)
ON(
fajta.FAJTAKULCS=zokni.FAJTAKULCS
AND
szin.SZINKULCS=zokni.SZINKULCS
)
ORDER BY SORSZAM
LIMIT 0, 20
");
while ($sor_zokni=mysql_fetch_assoc($eredmény_zokni)) {
echo $sor_zokni["SORSZAM"]
.$sor_zokni["FAJTA"]
.$sor_zokni["SZIN"]
.$sor_zokni["LEIRAS_1"]
.$sor_zokni["LEIRAS_2"]
.$sor_zokni["AR"];
}
?>
<?php
$eredmény_zokni=mysql_query("
SELECT *
FROM zokni
ORDER BY SORSZAM
LIMIT 0, 20
");
while ($sor_zokni=mysql_fetch_assoc($eredmény_zokni)) {
$fajta=mysql_result(mysql_query("SELECT FAJTA FROM fajta WHERE FAJTAKULCS=".$sor_zokni["FAJTAKULCS"]),0)
$szín=mysql_result(mysql_query("SELECT SZIN FROM szin WHERE SZINKULCS=".$sor_zokni["SZINKULCS"]),0)
echo $sor_zokni["SORSZAM"]
.$fajta
.$szín
.$sor_zokni["LEIRAS_1"]
.$sor_zokni["LEIRAS_2"]
.$sor_zokni["AR"];
}
?>
Harmadik lehetőség és megoldás
Az általad vázolt második lehetőségtől sírni fognak az angyalok :) Legalább
SELECT * FROM szin és SELECT * FROM fajta legyen az elején, ami egy-egy tömbbe gyűjti a szótártábláidat, majd ezekből a tömbökből a megflelő kulcshoz tartozó értéket írd ki.
(Amit felvázoltál az 41 lekérdezés, amihez 41szer fog lefutni a mysql SQL értlemezője, 41szer nyitja meg a táblákat stb stb stb...)
Bocs, nem voltam gépközelben.
A tömbbe gyűjtés ésszerűnek tűnik, bár egy régebbi kérdésemre, mi rendez gyorsabban, a PHP vagy a MySQL, a MySQL volt a válasz - tehát lehet, hogy nem is nyernék a tömbökkel. Végül is, a 2. megoldás 2 kis MySQL-lekérdezése is elég rövid, egysoros dolog. Közben új adattár-kapcsolatot nyitni természetesen nem kell, az él.
A hivatkozást köszönöm, kipróbálom; nekem nem sikerült ilyesmire bukkannom. Azért közben szívesen veszem mások tapasztalatait is.
Rendezés
Ezt nem értem. Ki mondta, hogy PHP-ban kell rendezni?
Túl tömör voltam
Szerinem
Szerintem
fajta.FAJTA,
szin.SZIN
FROM zokni
INNER JOIN fajta USING (FAJTAKULCS)
INNER JOIN szin USING (SZINKULCS)
ORDER BY SORSZAM
LIMIT 0, 20
INNER JOIN kulcsszavakkal sokkal átláthatóbb lesz a lekérdezés, és a JOIN-ok feltételei is egyértelműbbé válnak.
Ha rendesen indexelve van minden szükséges mező (FAJTAKULCS, SZINKULCS, SORSZAM), akkor ennek villámgyorsan le kell futnia egy 3000-es adatbázison (gondolom a fajták és sznek táblái nem túl nagyok)
Remélem, igazad van
Némi további magyarázat, miért is tetszene nekem is jobban a táblafűzéses megoldás [JOIN]: mert így pl. lehet rendezni a szín és a fajta szerint is rögtön ugyanabban az 1 lekérdezésben. Ez se megvetendő szempont.
Valóban az 1. a jó megoldás.
Még annyit: a USING szerkezetet azért nem használom, mert szándékosan eleve nincsenek egyező oszlopnevek még különböző táblákban sem; tehát a valós tábláimban még a FAJTAKULCS és SZINKULCS oszlopokat is másképp neveztem el a különböző táblákban. Oka: UNION szerkezetet is használok, s ott az egyező oszlopnév bonyodalmat okozna a rendezésnél (ORDER BY...).
Alias
Hátránya is van
Rossz helyre szúrtam be a megjegyzést. :(