2010-07-12 4 views
0

J'essaie d'optimiser une requête sql qui utilise order by clause. Lorsque j'utilise EXPLAIN, la requête affiche toujours "using filesort". J'applique cette requête à un forum de discussion de groupe dans lequel des balises sont attachées à des publications par des utilisateurs.SQL Query utilise toujours filesort dans l'ordre par la clause

Voici les 3 tables: J'utilise les utilisateurs, user_tag, tags

user_tag est la table de mappage d'association pour les utilisateurs et leurs mots clés.

CREATE TABLE `usertable` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`user_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, 
PRIMARY KEY (`user_name`), 
KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

CREATE TABLE `user_tag` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`user_id` int(11) unsigned NOT NULL, 
`tag_id` int(11) unsigned NOT NULL, 
`usage_count` int(11) unsigned NOT NULL, 
PRIMARY KEY (`id`), 
KEY `tag_id` (`tag_id`), 
KEY `usage_count` (`usage_count`), 
KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

Je mets à jour le use_count du côté serveur en utilisant la programmation. Voici la requête qui me pose problème. La requête est de trouver le tag_id et usage_count un nom d'utilisateur particulier, Triés par utilisation par ordre décroissant

select user_tag.tag_id, user_tag.usage_count 
    from user_tag inner join usertable on usertable.user_id = user_tag.user_id 
where user_name="abc" order by usage_count DESC; 

Voici l'expliquer sortie:

mysql> explain select 
    user_tag.tag_id, 
    user_tag.usage_count from user_tag 
    inner join usertable on 
    user_tag.user_id = usertable.user_id 
    where user_name="abc" order by 
    user_tag.usage_count desc; 

Explain output here

Qu'est-ce que devrais-je changer pour perdre ce "Using filesort"

+0

Vous ne montrez pas réellement la sortie d'EXPLAIN. Vous devez probablement également fournir la sortie de SHOW CREATE TABLE pour chaque table. Cela montrera les index sur les tables. –

+0

@George - J'ai posté le lien vers la sortie de EXPLAIN. Également modifié la question pour montrer les index. – vikmalhotra

+1

@OMG Poneys Je crois qu'ils sont synonymes dans la plupart des cas, sinon tous. –

Répondre

3

Je suis plutôt rouillé avec ceci, mais ici va.

La clé utilisée pour récupérer les rangées est pas le même que celui utilisé dans la clause ORDER BY:

http://dev.mysql.com/doc/refman/5.1/en/order-by-optimization.html

Comme mentionné par OMG Poneys, un index sur user_id, usage_count peut résoudre le filesort.

KEY `user_id_usage_count` (`user_id`,`usage_count`) 
+0

Merci pour ça. J'ai essayé mais cela ajoute juste une clé supplémentaire dans la colonne des clés possibles d'Explain.La colonne Extra d'expliquer reste intacte. – vikmalhotra

+0

la clé utilisée pour récupérer les lignes dans ce cas provient de la table "utilisable" alors que la clé utilisée pour l'ordre est de la table "user_tag". Donc, fondamentalement, je ne peux pas créer une clé qui a ces deux champs, non? – vikmalhotra

+0

@OMG Poneys - Je suppose que vous avez raison. Comme le champ principal dans ma table principale et la clé étrangère dans ma table de mappage d'association ne sont pas identiques, c'est pourquoi j'ai des problèmes. J'ai besoin d'ajuster un peu ma structure de table pour les rendre identiques. – vikmalhotra

1

L'utilisation de «filesort» n'est pas nécessairement mauvaise; Dans de nombreux cas, cela n'a pas vraiment d'importance.

En outre, son nom est quelque peu déroutant. La fonction filesort() n'utilise pas nécessairement les fichiers temporaires pour effectuer le tri. Pour les petits ensembles de données, les données sont triées en mémoire, ce qui est assez rapide. Sauf si vous pensez qu'il s'agit d'un problème spécifique (par exemple, après le profilage de votre application sur du matériel de production en laboratoire, la suppression de ORDER BY résout un problème de performances spécifique) ou si votre jeu de données est volumineux, vous ne devriez probablement pas inquiétez-vous.