Mailinglisten-Archive |
Ralf Eggert wrote: > Hi Liste, > > ich habe folgende 2 Tabellen (etwas vereinfacht): > > CREATE TABLE syst_sites ( > site_id tinyint(3) unsigned NOT NULL default '0', > site_name varchar(32) NOT NULL default '', > site_url varchar(64) default NULL, > site_email varchar(64) default NULL, > PRIMARY KEY (site_id) > ) TYPE=MyISAM; > > CREATE TABLE cat_links ( > link_id smallint(5) unsigned NOT NULL default '0', > link_site tinyint(3) unsigned NOT NULL default '0', > link_status enum('neu','genehmigt','geparkt','gesperrt') NOT NULL, > link_name varchar(64) NOT NULL default '', > link_url varchar(255) NOT NULL default '', > link_text varchar(255) NOT NULL default '', > PRIMARY KEY (link_id), > UNIQUE KEY un_link_url (link_site,link_url), > KEY fk_link_site (link_site), > KEY in_link_sitestatus (link_site,link_status) > ) TYPE=MyISAM; > > Ich moechte mit einem Select eine Uebersicht aller "Sites" mit der > Anzahl der Links gesamt und der Links mit Status "neu" erhalten. Mein > Select sieht so aus: > > SELECT syst_sites.*, > COUNT(a_links.link_id) AS site_linkcnt, > COUNT(b_links.link_id) AS site_linkcntnew > FROM syst_sites > LEFT JOIN cat_links AS b_links > ON site_id = b_links.link_site > AND FIND_IN_SET('neu', b_links.link_status) > LEFT JOIN cat_links AS a_links > ON site_id = a_links.link_site > GROUP BY site_id > ORDER BY site_id > > Das erste sonderbare Verhalten ist, dass das SELECT-Statement ueber 3 > Sekunden braucht, wenn ich die Reihenfolge der LEFT JOINs vertausche, > also zuerst auf "a_links" und dann auf "b_links" abfrage. Mache ich es > so wie oben angegeben, benoetigt das SELECT-Statement nur 0,03x > Sekunden. ja weil bei 'erst a dann b' nach dem ersten join wesentlich mehr datensätze zutreffen als bei 'erst b dann a' > > Das andere Problem ist, dass im Ergebnis bei "site_linkcntnew" der > gleiche Wert wie bei "site_linkcnt" steht, wenn es bei der "Site" > zumindest einen Link gibt, der den Status "neu" hat. Bei allen anderen > wird korrekterweise eine 0 ausgegeben. einfach mal ein SELECT * ohne das GROUP BY und das COUNT() und schau dir an was er denn ausgibt (mit LIMIT 50 oder so) > Kann mir jemand einen Tipp geben, wo das Problem liegen koennte oder wo > im SELECT-Statement mein Denkfehler liegen koennte? > > Danke und Gruss, > > Ralf > du könntest mit ein wenig CASE das auch über _ein_ LEFT JOIN lösen: *ungetested* SELECT syst_sites.*, COUNT(cat_links.link_id) AS site_linkcnt, SUM(CASE WHEN FIND_IN_SET('neu', cat_links.link_status) THEN 1 ELSE 0 END) AS site_linkcntnew FROM syst_sites LEFT JOIN cat_links ON syst_sites.site_id = cat_links.link_site GROUP BY site_id ORDER BY site_id oder so ähnlich... -- Sebastian Mendel www.sebastianmendel.de www.tekkno4u.de www.nofetish.com -- Infos zur Mailingliste, zur Teilnahme und zum An- und Abmelden unter -->> http://www.4t2.com/mysql
php::bar PHP Wiki - Listenarchive