SQL Sous-requête ou à l'INTÉRIEUR de la REJOINDRE?
J'ai les deux requêtes suivantes:
declare @UserId as int
set @UserId = 1
-- Query #1: Sub-query
SELECT
u.[Id] ,
u.[Name] ,
u.[OrgId] AS Organization,
(SELECT o.[Name] FROM Org o WHERE o.Id = u.OrgId) As OrganizationName,
[UserRoleId] AS UserRole,
[UserCode] AS UserCode,
[EmailAddress] As EmailAddress,
(SELECT SearchExpression FROM SearchCriteria WHERE UserId = @UserId AND IsDefault=1 ) AS SearchCriteria,
(SELECT PageSize FROM UserPreferences WHERE UserId = @UserId) AS UserPreferencePageSize,
(SELECT DrilldownPageSize FROM UserPreferences WHERE UserId = @UserId) AS UserPreferenceDrilldownPageSize
FROM [User] as u
WHERE u.Id = @UserId
-- Query #2: LEFT OUTER JOIN-query
SELECT
u.[Id] ,
u.[Name] ,
u.[OrgId] AS Organization,
(SELECT o.[Name] FROM Org o WHERE o.Id = u.OrgId) As OrganizationName,
[UserRoleId] AS UserRole,
[UserCode] AS UserCode,
[EmailAddress] As EmailAddress,
sc.SearchExpression As SearchExpression,
up.PageSize As PageSize,
up.DrilldownPageSize As DrilldownPageSize
FROM [User] as u
LEFT OUTER JOIN [UserPreferences] as up ON u.id = up.UserId
LEFT OUTER JOIN [SearchCriteria] as sc ON u.id = sc.UserId
WHERE ISNULL(sc.IsDefault,1)=1 AND u.Id = @UserId
Plan d'exécution de requête statistiques: (coût d'une Requête relative à lot)
- Requête#1 (Sous-Requête) : 56%
- Requête no 2 (JOIN) : 44%
Je thot la sous-requête serait optimale en raison de la sous-requête sera exécutée après la OÙ le filtre est appliqué. Les statistiques disent que la Requête n ° 2 - REJOINDRE approche est la meilleure.
Pls suggèrent. Aussi comme un modéré SQL-Server de l'utilisateur comment puis-je déterminer la requête est mieux (ou quelque chose d'autre, alors l'exécution du plan, si elle est plus utile)
Merci.
-- Requête n ° 3: Compléter la JOINTURE EXTERNE GAUCHE-requête SELECT u.[Id] , u.[Nom] , u.[OrgId] en tant QU'Organisation, l'u.OrgId Comme OrgId, o.[Name] OrganizationName, u.[UserRoleId] COMME UserRole, u.[Code d'utilisateur] COMME code d'utilisateur, u.[E-mail] Comme EmailAddress, sc.SearchExpression Comme SearchExpression, jusqu'.PageSize Comme PageSize, jusqu'.DrilldownPageSize Comme DrilldownPageSize DE [Utilisateur] comme u JOINTURE EXTERNE GAUCHE [UserPreferences] SUR u.id=.UserId JOINTURE EXTERNE GAUCHE [SearchCriteria] sc SUR u.id = sc.UserId JOINTURE EXTERNE GAUCHE [Org] o SUR o.Id = u.OrgId OÙ ISNULL(sc.IsDefault,1)=1 ET u.Id = @UserId
OriginalL'auteur Hemant Tank | 2009-11-24
Vous devez vous connecter pour publier un commentaire.
jointure est plus rapide que la sous-requête.
sous-requête fait pour les accès disque, pensez à disque dur de lire-écrire à l'aiguille(chef?) que va-et-vient lors de l'accès: l'Utilisateur, SearchExpression, PageSize, DrilldownPageSize, Utilisateur, SearchExpression, PageSize, DrilldownPageSize, Utilisateur... et ainsi de suite.
rejoindre œuvres par se concentrer l'opération sur le résultat des deux premières tables, les jointures serait de se concentrer le rejoindre sur la mémoire(ou mis en cache sur le disque) résultat de la première rejoint les tables, et ainsi de suite. moins de lecture-écriture de l'aiguille mouvement, donc plus rapide
OriginalL'auteur Michael Buen
La meilleure chose que vous pouvez faire est d'essayer les deux et de comparer ce qui vous donne les meilleures performances. Il est difficile de deuxième deviner ce que la requête de l'optimiseur va faire (vous pourriez écrire 2 requêtes différentes qui en définitive être optimisé pour le même plan d'exécution).
Pour comparer les performances assez, vous devriez vous assurer que vous essayer à partir d'un champ de jeu de niveau par compensation en bas le plan de l'exécution et du cache de données avant d'essayer chacun d'eux. Cela peut être fait en utilisant les commandes suivantes, mais seulement le faire sur un développement/test serveur de base de données:
L'approche que j'ai l'habitude de prendre consiste à exécuter à chaque requête, en 3 fois, avec le générateur de profils SQL en cours d'exécution si je peux surveiller la durée, les lectures, les CPU et écrit de la requête que je base ma décision.
par exemple
1) vider le cache à l'aide de commandes ci-dessus
2) exécuter la requête et d'enregistrer des statistiques
3) effacer le cache
4) exécuter la requête à nouveau
5) exécuter la requête à nouveau (cela va utiliser la mise en cache du plan d'exécution/de données)
Puis répétez l'opération pour la seconde requête pour comparer.
OriginalL'auteur AdaTheDev
Il dépendra en grande partie sur la cardinalité de vos données: si votre ligne de recherches sont minimes par rapport à la surcharge de
join
ing de vastes quantités de données (lorsque vous avez seulement besoin d'extraire un petit paragraphe à partir de ce joindre résultat), puis la ligne de l'option sera plus rapide. Mais si vous avez une charge importante avec en ligne sélectionne (par exemple, si votre résultat a un grand nombre de lignes, et vous êtes à l'appel d'une ligne select pour chaque ligne), puis la jointure sera plus rapide.Je ne vois pas de yourquestion le nombre de personnes concernées (c'est à dire le nombre de lignes) il est donc difficile de faire des commentaire qualitatif.
Par exemple, si votre résultat de 10 lignes, puis la ligne sélectionne sera effectuée pour chacune de ces dix lignes seulement, tandis que la jointure peut être impliquant beaucoup plus de lignes, qui sont ensuite réduit de façon sélective par les clauses where. Mais si vous avez un resultset de 10 millions de lignes, la ligne sélectionne va probablement tuer performance, depuis sa ligne par ligne.
EXEMPLE: imaginez que vous devez collecter une charge de briques (spécifié par la taille, etc.) de sur un chantier de construction et les peindre en bleu.
inline sélectionnez = la Sélection de toutes les briques que vous avez besoin et de les peindre à la main.
rejoindre = dump toutes les briques dans un énorme seau de peinture, anf puis choisissez ceux que vous avez besoin
Si vous voulez seulement de se retrouver avec 10 briques, il est beaucoup plus rapide pour sélectionner, puis peinture à la main. Si vous voulez un million de briques, alors la masse de peinture dans un bac d'abord est le chemin à parcourir.
OriginalL'auteur davek
Le coût relatif d'un plan d'exécution n'est pas toujours un indicateur fiable de la performance.
Je suppose que de votre sql que seulement 1 ligne doit être renvoyée. Prévoyant que le code d'utilisateur est une clé unique de l'Utilisateur, alors la performance de votre 2 approches similaires sur la plupart des bases de données relationnelles.
Choses à garder à l'esprit serait:
OriginalL'auteur Steve De Caux