2010-03-08 4 views
2

J'ai une jointure qui supprime les lignes qui correspondent à une autre table, mais les champs de jointure doivent être un grand varchar (250 caractères). Je sais que ce n'est pas idéal mais je ne peux pas penser à un meilleur moyen. Voici ma question:Les jointures SQL sur les champs varchar expirent

DELETE P 
FROM dbo.FeedPhotos AS P 
INNER JOIN dbo.ListingPhotos AS P1 ON P.photo = P1.feedImage 
INNER JOIN dbo.Listings AS L ON P.accountID = L.accountID 
WHERE P.feedID = @feedID 

Cette requête est constamment hors délai, même si il y a moins de 1000 lignes dans la table ListingPhotos.

Toute aide serait appréciée.

+0

sont là des indices sur '' P.photo' et P1.feedImage'? Ceux-ci seraient certainement aider ... –

Répondre

3

je serais probablement commencer par suppression de cette ligne, car il ne semble pas faire quoi que ce soit:

INNER JOIN dbo.Listings AS L ON P.accountID = L.accountID 

Il pourrait ne pas avoir beaucoup de lignes dans ListingPhotos, mais s'il y a beaucoup de lignes dans Listings alors la jointure ne sera pas optimisée.

Vérifiez également votre indexation, car toute jointure est forcément lente sans les index appropriés. Bien que vous devriez généralement essayer d'éviter de rejoindre des champs de caractères de toute façon, c'est généralement un signe que les données ne sont pas normalisées correctement.

+0

Rejoindre sur varchar est acceptable si c'est la clé naturelle et vous n'avez pas utilisé une clé de substitution (demandez Joe Celko :-). Vous devrez ajouter une contrainte ou un index unique sur la colonne varchar si c'était la valeur unique et vous avez choisi une identité int comme PK pour garder l'intégrité des données – gbn

+0

@gbn: Si votre clé naturelle est de 250 caractères, il est temps pour un substitut; quelque part, il y a un compromis entre la touche de performance INSERT/UPDATE/DELETE de plusieurs index et la touche de performance SELECT d'une clé de plus de 8 octets, mais 250 est de l'autre côté de la clé. clôture. Aussi, je ne ferais pas confiance à Joe Celko pour me dire correctement l'heure de la journée. : P – Aaronaught

+0

Accepter tout ce qui précède ... – gbn

0

Il suffit d'ajouter un index.

CREATE INDEX idx_feedPhotos_feedid 
    ON dbo.FeedPhotos (feedId) 
1

Je considérerais:

  • réécriture à l'utilisation EXISTE. Cela arrêtera le traitement si une ligne se trouve plus fiable reposant alors sur JOIN qui peut avoir plusieurs lignes intermédiaires (qui est ce que dit Aaronaught)

  • assurer que tous les types de données correspondent exactement . Toutes les différences de longueur ou de type signifieront qu'aucun index ne sera utilisé

  • En parlant de cela, avez-vous un index (approximatif) sur feedid, photo et accountid?

Quelque chose comme:

DELETE 
    P 
FROM 
    dbo.FeedPhotos AS P 
WHERE 
    P.feedID = @feedID 
    AND 
    EXISTS (SELECT * FROM 
      dbo.ListingPhotos P1 
      WHERE P.photo = P1.feedImage) 
    AND 
    EXISTS (SELECT * FROM 
      dbo.Listings L 
      WHERE P.accountID = L.accountID) 
Questions connexes