2010-09-23 6 views
0

J'ai une requête SQL complexe avec « sous-requêtes » imbriquées que je veux optimiseront besoin aider à optimiser MySQL requête

SELECT 
'likes' `type`, 
entry_date item_date, 
CASE `type` 
    WHEN 'entry_id' THEN entry_id 
    WHEN 'member_id' THEN f.member_id 
    WHEN 'topic_id' THEN entry_id 
END  
AS item_id, 
CASE `type` 
    WHEN 'entry_id' THEN (SELECT title FROM exp_weblog_titles WHERE entry_id=item_id) 
    WHEN 'member_id' THEN (SELECT screen_name FROM exp_members WHERE member_id=item_id) 
    WHEN 'topic_id' THEN (SELECT title FROM exp_forum_topics WHERE topic_id=item_id) 
END  
AS item_title, 
CASE `type` 
    WHEN 'member_id' THEN (SELECT username FROM exp_members WHERE member_id=item_id) 
    ELSE '' 
END  
AS item_url_title, 
f.type parent_type, 
CASE `type` 
    WHEN 'entry_id' THEN (SELECT weblog_id FROM exp_weblog_titles WHERE entry_id=item_id) 
    WHEN 'member_id' THEN '' 
    WHEN 'topic_id' THEN (SELECT forum_id FROM exp_forum_topics WHERE topic_id=item_id) 
END  
AS parent_id, 
CASE `type` 
    WHEN 'entry_id' THEN '' 
    WHEN 'member_id' THEN '' 
    WHEN 'topic_id' THEN (SELECT forum_name FROM exp_forums WHERE forum_id=parent_id) 
END  
AS parent_title,   
m.member_id actor_member_id, 
screen_name actor_screen_name, 
username actor_username, 
photo_filename actor_photo, 
avatar_filename actor_avatar 
FROM exp_favorites f, exp_members m 
WHERE f.member_id=m.member_id 

Comme vous pouvez le remarquer, dans les sous-requêtes une table de sont interrogés plusieurs fois pour la même ligne, mais une champ différent.
Comme, j'ai

SELECT screen_name FROM exp_members WHERE member_id=item_id 

et

SELECT username FROM exp_members WHERE member_id=item_id 

que je vivrais pour voir combinés pour mimize le nombre de reuests et la charge du serveur.

Existe-t-il un moyen de le faire? Des conseils?

UPD. structure de la table est le suivant:
CREATE TABLE exp_favorites (
favorites_id int (10) unsigned NON auto_increment NULL,
type varchar (16) NOT défaut NULL 'entry_id',
author_id int (10) unsigned NON par défaut NULL « 0 »,
entry_id int (10) unsigned NOT NULL,
member_id int (10) unsigned NOT NULL,
site_id smallint (3) NOT NULL par défaut non signé '1',
entry_date int (10) un signé NOT NULL,
notes texte NOT NULL,
public char (1) NOT NULL default 'y',
clé primaire (favorites_id),
KEY author_id (author_id),
KEY entry_id (entry_id),
KEY member_id (member_id),
KEY site_id (site_id),
KEY public (public),
KEY type (type)
)

+0

Pouvez-vous poster votre structure de table ici? Votre base de données est-elle normalisée? –

+0

a mis à jour la publication avec des informations sur la structure de la table. Je ne connais pas grand-chose à la normalisation, mais cela me semble normalisé. –

Répondre

1

Vous pouvez faire quelque chose comme ceci:

SELECT 
'likes' `type`, 
entry_date item_date, 
CASE `type` 
    WHEN 'entry_id' THEN entry_id 
    WHEN 'member_id' THEN f.member_id 
    WHEN 'topic_id' THEN entry_id 
END  
AS item_id, 
CASE `type` 
    WHEN 'entry_id' THEN wt.title 
    WHEN 'member_id' THEN m2.screen_name 
    WHEN 'topic_id' THEN ft.title 
END  
AS item_title, 
... 
FROM exp_favorites f 
inner join exp_members m ON f.member_id=m.member_id 
left outer join exp_weblog_titles wt on wt.entry_id=f.item_id 
left outer join exp_members m2 on m2.entry_id=f.item_id 
left outer join exp_forum_topics ft on ft.entry_id=f.item_id 
+0

cela ne semble pas être une option car f.item_id peut se rapporter à l'enregistrement dans l'une des 3 tables, et donc la jointure deviendra juste énorme. Ou ai-je tort ici? –

+0

@runner: examine les conditions de jointure dans les trois dernières jointures de table - toutes proviennent de f.item_id, dans le champ approprié de chaque table. –

+0

@RedFilter, je pense que quelques jointures à gauche doivent être ajustées - exp_members est seulement joint à member_id, donc il n'y a pas besoin de m2, alors que le sujet du forum est joint sur topic_id et parent_id mais pas entry_id. –