2015-04-05 1 views
1

Cette requête (JOIN):REJOIGNEZ en utilisant filesort, ne pas l'utiliser sous-requête

SELECT DISTINCT Token 
FROM ID 
INNER JOIN Tokens ON ID.Token_ID = Tokens.Token_ID 
WHERE ID.Type = 'org' 
OR (
ID.Type = 'lemma' 
AND Tokens.Value <3 
) 
ORDER BY ID.Token_ID 
LIMIT 200 

est en utilisant filesort. Cette requête (SUBQUERY):

SELECT DISTINCT Token 
FROM ID 
WHERE TYPE = 'org' 
OR (

TYPE = 'lemma' 
AND Token_ID 
IN (

SELECT Token_ID 
FROM Tokens 
WHERE Value <3 
) 
) 
ORDER BY Token_ID 
LIMIT 200 

n'utilise pas de fichier. Je sais que JOIN devrait être plus rapide que la sous-requête, donc je pense que j'ai besoin de quelques index supplémentaires: quels index dois-je ajouter pour ne pas utiliser filesort dans la requête de jointure?

Répondre

0

Voici une légère variation de la requête:

SELECT Token 
FROM ID 
WHERE TYPE = 'org' 
UNION 
SELECT Token 
FROM ID 
WHERE TYPE = 'lemma' AND 
     EXISTS (SELECT t.Token_ID 
       FROM Tokens t 
       WHERE t.Token_ID = ID.Token_ID AND t.Value < 3 
      ) 
ORDER BY Token 
LIMIT 200; 

La variation est que la ORDER BY utilise Token plutôt que Token_ID. Ce dernier n'a vraiment aucun sens, et je suis surpris qu'il ne génère pas d'erreur. Pour cette requête, vous voulez dans l'index sur ID(type, Token_Id, Token) et ID(Type, Token) et Tokens(Token_Id, Value).

+0

Merci pour la réponse. La deuxième requête donne la même sortie que la première, mais elle n'est probablement pas claire: je dois vérifier la valeur (<3) seulement si le type est "lemma". Votre requête renvoie tout, car la condition EXISTS est toujours satisfaite. La deuxième requête est dans le formulaire "WHERE conditionA OR conditionB", qui, oui, peut être traduit dans une requête équivalente avec une union au lieu de l'OR. La deuxième requête est déjà efficace et n'utilise pas de fichier, mais ma question est: est-ce que je peux faire la même chose avec JOIN? Je ne sais pas quels index dois-je ajouter pour utiliser la requête JOIN sans l'archive de fichiers. – user2502368