2011-03-31 3 views
6

J'ai une table avec beaucoup de données et je dois la joindre avec d'autres grandes tables.SQL - Filtrage de grandes tables avec jointures - bonnes pratiques

Seulement une petite partie de ma table est réellement pertinente pour moi à chaque fois.

Quand est-il préférable de filtrer mes données?

  1. Dans la clause where de SQL.

  2. Créer une table temporaire avec les données spécifiques et alors seulement le rejoindre.

  3. Ajouter le prédicat à la première jointure interne clause ON.

  4. Une autre idée.

1.

Select * 
From RealyBigTable 
Inner Join AnotherBigTable On … 
Inner Join YetAnotherBigTable On … 
Where RealyBigTable.Type = ? 

2.

Select * 
Into #temp 
From RealyBigTable 
Where RealyBigTable.Type = ? 

Select * 
From #temp 
Inner Join AnotherBigTable On … 
Inner Join YetAnotherBigTable On … 

3.

Select * 
From RealyBigTable 
Inner Join AnotherBigTable On RealyBigTable.type = ? And … 
Inner Join YetAnotherBigTable On … 

Une autre question: Que se passe- premier? Join ou Where?

Répondre

11

Parce que vous utilisez des inner join WHERE ou JOIN débat ne dépend que de votre goût et de style. Personnellement, j'aime conserver les liens entre les deux tables (par exemple, la contrainte de clé étrangère) dans la clause ON, et les filtres réels contre les données dans la clause WHERE.

SQL Server va analyser la requête dans le même arbre symbolique, et donc élaborer des plans d'exécution des requêtes identiques.

Si vous utilisez [GAUCHE/DROITE] REJOINT au lieu EXTERIEUR, il fait un monde de différence puisque non seulement les performances probablement différent, mais aussi très probablement les résultats.


Pour répondre à vos autres questions:

Quand est-ce préférable de filtrer mes données?

  1. Dans la clause where de SQL.
  2. Créer une table temporaire avec les données spécifiques et ensuite seulement la joindre.
  3. Ajoutez le prédicat à la première clause de jointure interne ON.
  4. Une autre idée.

Dans la clause WHERE ou ON, les deux sont considérés comme identiques. Pour 3, la "jointure interne première" n'a aucune pertinence. Dans un scénario INNER JOIN à plusieurs tables, peu importe ce qui se passe en premier (dans la requête), car l'optimiseur de requête va mélanger l'ordre comme bon lui semble.

En utilisant une table temporaire est complètement inutile et ne va pas aider, parce que vous avez pour extraire la partie pertinente de toute façon - qui est ce que JOIN ferait aussi bien.De plus, si vous avez un bon index sur les conditions JOIN/filtre WHERE, l'index ne sera utilisé que pour visitez les données pertinentes sans regarder le reste de la table (s).

+1

OK. Mais n'est-il pas préférable de mettre les données dans une table temporaire et seulement ensuite (interne) rejoindre les différentes tables? –

+0

@gil - voir la réponse éditée – RichardTheKiwi

1

Vous devez placer votre requête dans le studio de gestion, cocher "inclure le plan d'exécution" et l'exécuter. De cette façon, vous obtiendrez la réponse exacte à ce que le serveur SQL a fait avec votre requête. A partir de là, vous pouvez aller de l'avant avec l'optimisation.

En général:

  • Les colonnes utilisées pour joindre doivent être indexées
  • Utilisez le filtre le plus discriminant premier
0

Dans un planificateur de requêtes en fonction du coût décent ce qui se passe est (votre cas)

  1. conditions de jointure et où les conditions sont analysées au même niveau

  2. le type de jointure et des statistiques détermine le chemin (ce qui se passe en premier) - de telle sorte que les plus petits résultats intermédiaires sont récupérés (moins d'E/S> recherche rapide)