2013-05-02 10 views
5

Ho una query, in generale, molto semplice e non capisco perché il piano di esecuzione effettivo mi mostra un avviso "No Join Predicate" subito dopo la selezione iniziale su un nodo "Nested Loops"."No Join Predicate" quando si aggiunge una condizione aggiuntiva - perché?

Penso che la query sia piuttosto auto-esplicativa: ho utenti e hanno UserSubscriptions ai Feed (m: n) - Voglio interrogare tutti i FeedItem da un Feed a cui l'utente deve essere iscritto, quindi questa query fa questo molto bene:

select fi.Title, fi.Content, fi.Published 
from [User] u 
inner join UserSubscription us on u.id = us.UserId 
inner join Feed f on f.id = us.FeedId 
inner join FeedItem fi on fi.FeedId = f.Id 
where u.EMailAddress = '[email protected]' 
and f.id = 3 
and fi.Inserted > getdate() - 30 

la parte interessante è che non v'è alcun avviso finché io lasciare fuori questa condizione:

and f.id = 3 

appena rimuovo questo, l'avviso relativo alla mancanza predicato di join scompare . Non capisco la causa di questo avvertimento qui.

Qualsiasi aiuto per capire questo sarebbe molto apprezzato!

Grazie b.

+5

qv http://dba.stackexchange.com/questions/34193/should-i-be-alarmed-by-this-no-join-predicate-warning e http://dba.stackexchange.com/questions/ 35082/what-exact-does-no-join-predicate-mean-in-sql-server - in breve, questo non è * automaticamente * una cosa negativa – AakashM

+0

Ok per quanto ne so - nel mio caso SQL Server ottimizzerebbe il mio Join on Feed come condizione per Feed.Id = 3 rende il join inutile? Quindi questo è il motivo per cui non esiste più un predicato di join per questo tavolo? Ok, per quanto riguarda le prestazioni ... questo non dovrebbe essere un problema. Logicamente dovrò pensarci perché il Feed Join <-> UserSubscriptions è lì per filtrare qualsiasi Feed che l'Utente sia realmente sottoscritto in quanto non è detto che l'Utente sia iscritto al Feed con ID 3 in questo esempio. Grazie! –

risposta

3

La ragione per cui non c'è bisogno di JOIN sul piano di alimentazione è perché:

  1. f.id = us.FeedId = fi.FeedId
  2. L'(feed) tavolo f non viene utilizzato/necessaria in qualsiasi altra parte della query (o SELECTWHERE)

Ecco una query più ottimizzato:

select fi.Title, fi.Content, fi.Published 
from [User] u 
inner join UserSubscription us on u.id = us.UserId and us.FeedId = 3 
inner join FeedItem fi on fi.FeedId = us.FeedId 
where u.EMailAddress = '[email protected]' 
and fi.Inserted > getdate() - 30 

Limitando prima un FeedId particolare, mantieni il set di dati più piccolo e quindi più veloce. L'ottimizzatore può modificare la query per questo per voi; Non ne sono sicuro.

+2

Non sono d'accordo, puoi eliminare quell'unione. Se Feed non ha un id di 3 allora non sarebbe nella query OP ma sarebbe nella query che hai postato. – Paparazzi

+1

@Blam - Pur essendo vero, sono fiducioso nelle mie ipotesi sullo schema e sui vincoli del sistema dell'OP in base alla query originale e ai nomi delle sue tabelle. Devo ammettere che c'è una possibilità della situazione che proponi. –

+0

Grazie @ coge.soft - ha assolutamente senso. È probabile che lo Strumento di ottimizzazione rimuoverà questo collegamento e spiegherebbe il motivo per cui viene visualizzato l'avviso "Nessun annuncio Predicato". Roba davvero interessante Grazie anche a te, Blam - ma coge.soft ha ragione, il mio schema richiede che un Feed con Id = 3 esista nel Feed quando tale voce esiste in UserSubscription. –

Problemi correlati