2009-09-05 8 views
7

J'essaie d'optimiser mes requêtes mysql pour éviter d'utiliser 'temporary, using filesort'. Je pourrais utiliser un peu d'aide. Premier; voici l'expliquerUtilisation temporaire, using filesort une mauvaise idée dans mysql?

est ici de la requête

select pf.*,m.login,m.avatar 
from profile_friends pf, members m 
where pf.friend_id = m.id and pf.member_id = 16586 
order by m.lastLogin desc 
limit 0,24; 


mysql> EXPLAIN select pf.*,m.login,m.avatar from profile_friends pf, members m where pf.friend_id = m.id and pf.member_id = 16586 order by m.lastLogin desc limit 0,24; 
+----+-------------+-------+--------+-----------------------------------------------------+-----------------+---------+--------------------------+------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys          | key    | key_len | ref      | rows | Extra          | 
+----+-------------+-------+--------+-----------------------------------------------------+-----------------+---------+--------------------------+------+----------------------------------------------+ 
| 1 | SIMPLE  | pf | ref | member_id_index,friend_id_index      | member_id_index |  4 | const     | 160 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | m  | eq_ref | PRIMARY,member_id_privacy_index,id_last_login_index | PRIMARY   |  4 | mydb.pf.friend_id  | 1 | Using where         | 

Il y a 2 tables impliquées. ProfileFriends (pf), et Membres (m). Cette requête essaie simplement de trouver les 24 amis 'récents' pour cet identifiant de membre particulier. Les moyennes récentes trient par date LastLogin.

Merci

Répondre

17

C'est un problème? Ouais.

Est-ce un problème lorsque vous avez 160 lignes? Nan. "Filesort" est une méthode, pas la création réelle d'un fichier et le tri. Si nous parlions de 160 000 lignes au lieu de 160 lignes, il y aurait probablement lieu d'envisager d'autres optimisations.

Modifier: De plus, vous avez omis l'heure d'exécution réelle de la requête. Vous frappez des index et ne travaillez qu'avec une poignée de lignes. Si cette requête prend plus d'une fraction de seconde, cela ne vaut probablement pas la peine d'envisager une optimisation.

+3

+1 Oui, pour 160 lignes, MySQL peut même conserver la table temporaire en mémoire, sans l'écrire sur le disque. "Filesort" est un peu trompeur, cela signifie seulement qu'il est tri sans le bénéfice d'un index. –

1

C'est le moyen le plus efficace d'écrire cette requête.

Assurez-vous que pf.friend_id,et m.id contiennent des indices. Ensuite, il utilisera les indices pour rejoindre les tables et filtrer les résultats.

Ce genre va apparaître, à cause de votre order by.

+4

MySQL utilisera soit l'index sur 'pf.friend_id' soit celui sur' pf.member_id' mais il n'utilisera pas les deux, donc pas besoin de créer des index superflus. Il pourrait cependant utiliser un index sur '(member_id, friend_id)'. –

2

Je pense que vous devriez être en mesure d'éviter le temporaire/filesort avec un index sur members (id,lastLogin)— dans cet ordre — mais pour ce type de requêtes, il est surpuissant et à en juger par votre EXPLIQUER il semble que vous avez déjà essayé?

Vous pouvez le compléter avec une CLÉ PRIMAIRE/UNIQUE sur profile_friends (member_id,friend_id) et voir comment cela fonctionne.

En dernier recours, si cette requête est exécutée si souvent et avec tant d'enregistrement que vous devez avoir le plus rapide SELECT possible, vous pouvez dénormaliser votre table et ajouter une copie de votre colonne members.lastLogin-profile_friends avec un index sur (member_id,lastLogin). Avec cela, vous n'auriez pas de jointure, pas de fichier, pas de rien. D'un autre côté, vous auriez de grandes requêtes UPDATE chaque fois que quelqu'un avec beaucoup d'amis se connecte. Encore une fois, cela semble complètement exagéré pour le genre de nombres dont vous parlez.

J'ai presque oublié de répondre à la question initiale:

L'utilisation temporaire, en utilisant filesort une mauvaise idée dans une base MySQL?

Non, ce n'est pas le cas. Si vous pouvez l'optimiser facilement, vous devriez toujours chercher des requêtes "filesort-free", mais sinon, à moins qu'elles ne posent un réel problème de performance, vous ne devriez pas vous en préoccuper. Filesort fait partie de l'exécution normale d'une requête.

Questions connexes