Autor | Zpráva | ||
---|---|---|---|
Peter123 Profil * |
#1 · Zasláno: 11. 10. 2012, 10:08:13
Zdravím,
mám nasledujúcu úlohu: potrebujem vyhladat všetky inzeraty, ktoré majú vybrané nasledujúce parametre: Lokalita: [x] v obci [x] mimo obce [ ] v meste Stav [ ] povodny [x] novostavba [x] kompletna rekonstrukcia [ ] starsia budova Siete [x] voda [ ] plyn [x] elektrina ciže: všetky inzeráty, ktoré sú: v obci ALEBO mimo obce A SÚ novostavba ALEBO kompletna rekonstrukcia A SÚ s vodou alebo elektrinou. 1. mám v DB tabulku inzeráty: ------------------------------------- id, primary, int(11) title, varchar(100) 2. tabulka inzeraty_paramvalues: ------------------------------------------ inzerat_id, int(11) paramvalue_id, varchar(20) (napr.: voda, elektrina, novostavba...) 3. dotaz do DB ------------------ select * from inzeraty where id IN (SELECT inzerat_id FROM inzeraty_paramvalues WHERE paramvalue_id in ('v_obci', 'mimo_obce') AND inzerat_id IN ( SELECT inzerat_id FROM inzeraty_paramvalues WHERE paramvalue_id in ('novostavba', 'rekonstrukcia') AND inzerat_id IN ( SELECT inzerat_id FROM inzeraty_paramvalues WHERE paramvalue_id in ('voda', 'elektrina') ) ) ) Problém je v tom, že pri väčšom počte inzerátov a parametrov a aplikuje WHERE na velmi vela záznamov.. Otázka je, či by to šlo nejak zoptimalizovať alebo inak navrhúť štruktúru DB. |
||
mimochodec Profil |
#2 · Zasláno: 11. 10. 2012, 10:20:15
nebylo by jednodušší toto?
WHERE paramvalue_id in ('voda', 'elektrina') AND paramvalue_id in ('novostavba', 'starostavba') ... Druhá věc je ta konstrukce samotná. Pracovat s řetězci 'v_obci', 'mimo_obce' apod je mnohem náročnější, než si udělat patřičné sloupce a v nich uchovávat integer. |
||
Kajman Profil |
#3 · Zasláno: 11. 10. 2012, 11:02:49
V jaké tabulce si uchováváte rozdělení parametrů na lokalita, stav a siete? S ní by to mělo jít.
|
||
Peter123 Profil * |
#4 · Zasláno: 11. 10. 2012, 11:12:36
Kajman:
No to je zatiaľ otázka.. Momentálne riešenie je také, že to nebude v DB, ale iba v PHP asociatívnom poli: <?php $params = array( 'stav' => array( '0' => 'novostavba', '1' => 'kompletna rekonstrukcia' .... ) ); ?> |
||
Kajman Profil |
Tím přicházíte o možnost ladného a nejspíše i rychlejšího řešení na straně db.
Mohly by fungovat přibližně takovéto dotazy... SELECT i.* FROM inzeraty i INNER JOIN (SELECT DISTINCT inzerat_id FROM inzeraty_paramvalues WHERE inzerat_id = i.id AND paramvalue_id IN ( 'v_obci', 'mimo_obce' )) p1 ON i.id = p1.inzerat_id INNER JOIN (SELECT DISTINCT inzerat_id FROM inzeraty_paramvalues WHERE inzerat_id = i.id AND paramvalue_id IN ( 'novostavba', 'rekonstrukcia' ) ) p2 ON i.id = p2.inzerat_id INNER JOIN (SELECT DISTINCT inzerat_id FROM inzeraty_paramvalues WHERE inzerat_id = i.id AND paramvalue_id IN ( 'voda', 'elektrina' )) p3 ON i.id = p3.inzerat_id SELECT i.* FROM inzeraty i INNER JOIN (SELECT inzerat_id FROM (SELECT inzerat_id, 'lokalita' typ FROM inzeraty_paramvalues WHERE paramvalue_id IN ( 'v_obci', 'mimo_obce' ) UNION ALL SELECT inzerat_id, 'stav' typ FROM inzeraty_paramvalues WHERE paramvalue_id IN ( 'novostavba', 'rekonstrukcia' ) UNION ALL SELECT inzerat_id, 'siete' typ FROM inzeraty_paramvalues WHERE paramvalue_id IN ( 'voda', 'elektrina' )) x GROUP BY inzerat_id HAVING Count(DISTINCT typ) = 3) t ON i.id = t.inzerat_id SELECT i.* FROM inzeraty i WHERE EXISTS (SELECT inzerat_id FROM inzeraty_paramvalues WHERE inzerat_id = i.id AND paramvalue_id IN ( 'v_obci', 'mimo_obce' )) AND EXISTS (SELECT inzerat_id FROM inzeraty_paramvalues WHERE inzerat_id = i.id AND paramvalue_id IN ( 'novostavba', 'rekonstrukcia' ) ) AND EXISTS (SELECT inzerat_id FROM inzeraty_paramvalues WHERE inzerat_id = i.id AND paramvalue_id IN ( 'voda', 'elektrina' )) Těžko říci, co bude u rozsáhlejších dat svižnější. Každopádně je vhodný index na paramvalue_id. A paramvalue_id by klidně mohlo být číslo z číselníku, který Vám chybí. Ať se nemusí pracovat s řetězcem. |
||
Peter123 Profil * |
#6 · Zasláno: 11. 10. 2012, 19:30:30
Kajman:
Hmm, ďakujem, skúsim to otestovať. Každopádne stĺpce inzerat_id a paramvalue_id tvoria primarny kľúč, takže to by mohlo pomôcť, a ten číselník ma tiež napadol. Ďakujem za pomoc |
||
Kajman Profil |
#7 · Zasláno: 11. 10. 2012, 21:23:21
Peter123:
„Každopádne stĺpce inzerat_id a paramvalue_id tvoria primarny kľúč, takže to by mohlo pomôcť“ Unikátní index na kombinaci sloupců (inzerat_id, paramvalue_id), v tomto pořadí, není použitelný pro tyto dotazy hledající inzeráty podle hodnoty v paramvalue_id. Proto bude lepší i další index nad druhým sloupcem. Číselníková tabulka je krok správným směrem. |
||
Časová prodleva: 12 let
|
0