Plus: SQL Server 2012 montre une certaine amélioration de la performance dans ce domaine, mais ne semble pas s'attaquer aux questions spécifiques indiquées ci-dessous. Cette
devrait apparemment être corrigé dans la prochaine version majeure après
SQL Server 2012!
Votre plan montre le seul inserts sont paramétrés à l'aide de procédures (éventuellement auto paramétrable) afin d'analyser/temps de compilation pour ceux-ci devraient être minimes.
Je pensais regarder cela d'un peu plus si donc mis en place une boucle (script) et tenté d'ajuster le nombre d' VALUES
de clauses et de l'enregistrement de la compilation.
J'ai ensuite divisé le temps de compilation par le nombre de lignes pour obtenir la moyenne de la compilation par la clause. Les résultats sont ci-dessous
Jusqu'à 250 VALUES
clauses présentes au moment de la compilation / nombre de clauses a une légère tendance à la hausse, mais rien de trop dramatique.
Mais ensuite, il ya un changement soudain.
Cette section des données est indiqué ci-dessous.
+------+----------------+-------------+---------------+---------------+
| Rows | CachedPlanSize | CompileTime | CompileMemory | Duration/Rows |
+------+----------------+-------------+---------------+---------------+
| 245 | 528 | 41 | 2400 | 0.167346939 |
| 246 | 528 | 40 | 2416 | 0.162601626 |
| 247 | 528 | 38 | 2416 | 0.153846154 |
| 248 | 528 | 39 | 2432 | 0.157258065 |
| 249 | 528 | 39 | 2432 | 0.156626506 |
| 250 | 528 | 40 | 2448 | 0.16 |
| 251 | 400 | 273 | 3488 | 1.087649402 |
| 252 | 400 | 274 | 3496 | 1.087301587 |
| 253 | 400 | 282 | 3520 | 1.114624506 |
| 254 | 408 | 279 | 3544 | 1.098425197 |
| 255 | 408 | 290 | 3552 | 1.137254902 |
+------+----------------+-------------+---------------+---------------+
Le plan de mise en cache de taille qui a été de plus en plus de façon linéaire tombe tout d'un coup, mais compile-time augmente 7 fois et CompileMemory tire vers le haut. C'est le point de coupure entre le plan d'une auto paramétrées, un (1 000 paramètres) à une non paramétrées. Par la suite, il semble pour obtenir linéairement de moins en moins efficace (en termes de nombre de valeur clauses traitées dans un temps donné).
Je ne sais pas pourquoi cela devrait être. On peut penser que lorsqu'il est en train de compiler un plan pour certaines valeurs littérales il doit effectuer certaines activités qui ne sont pas à l'échelle linéaire (comme le tri).
Il ne semble pas affecter la taille du cache de plan de requête lorsque j'ai essayé une requête entièrement composé de lignes en double et ne nuit ni à l'ordre de la sortie de la table de constantes (et que vous insérez dans un tas de temps consacré au tri serait inutile de toute façon, même si c'était le cas).
En outre, si un index cluster est ajoutée à la table, le plan montre encore un tri explicite étape de sorte qu'il ne semble pas être le tri au moment de la compilation pour éviter un tri au moment de l'exécution.
J'ai essayé de regarder ce dans un débogueur, mais les symboles publics pour ma version de SQL Server 2008 ne semblent pas être disponibles si au lieu de cela, j'ai dû regarder l'équivalent UNION ALL
de la construction dans SQL Server 2005.
Typique de trace de la pile est en dessous
sqlservr.exe!FastDBCSToUnicode() + 0xac bytes
sqlservr.exe!nls_sqlhilo() + 0x35 bytes
sqlservr.exe!CXVariant::CmpCompareStr() + 0x2b bytes
sqlservr.exe!CXVariantPerformCompare<167,167>::Compare() + 0x18 bytes
sqlservr.exe!CXVariant::CmpCompare() + 0x11f67d bytes
sqlservr.exe!CConstraintItvl::PcnstrItvlUnion() + 0xe2 bytes
sqlservr.exe!CConstraintProp::PcnstrUnion() + 0x35e bytes
sqlservr.exe!CLogOp_BaseSetOp::PcnstrDerive() + 0x11a bytes
sqlservr.exe!CLogOpArg::PcnstrDeriveHandler() + 0x18f bytes
sqlservr.exe!CLogOpArg::DeriveGroupProperties() + 0xa9 bytes
sqlservr.exe!COpArg::DeriveNormalizedGroupProperties() + 0x40 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x18a bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!CQuery::PqoBuild() + 0x3cb bytes
sqlservr.exe!CStmtQuery::InitQuery() + 0x167 bytes
sqlservr.exe!CStmtDML::InitNormal() + 0xf0 bytes
sqlservr.exe!CStmtDML::Init() + 0x1b bytes
sqlservr.exe!CCompPlan::FCompileStep() + 0x176 bytes
sqlservr.exe!CSQLSource::FCompile() + 0x741 bytes
sqlservr.exe!CSQLSource::FCompWrapper() + 0x922be bytes
sqlservr.exe!CSQLSource::Transform() + 0x120431 bytes
sqlservr.exe!CSQLSource::Compile() + 0x2ff bytes
Donc, la sortie de noms dans la trace de la pile, il semble passer beaucoup de temps à comparer des chaînes de caractères.
Le présent article indique que DeriveNormalizedGroupProperties
est associé avec ce que l'on appelait la normalisation étape de traitement de la requête
Cette étape est maintenant appelé liaison ou algebrizing et il prend l'expression arbre d'analyse de la sortie de la précédente analyser la scène et les sorties d'un algebrized expression de l'arbre (processeur de requête de l'arbre) pour aller de l'avant à l'optimisation (trivial plan d'optimisation dans ce cas) [ref].
J'en ai essayé un plus expérience (Script) qui a été ré-exécuter l'analyse d'origine mais en regardant les trois cas différents.
- Les Nom et prénom des Chaînes de caractères de longueur de 10 caractères avec pas de doublons.
- Les Nom et prénom des Chaînes de caractères de longueur 50 caractères, sans doublons.
- Les Nom et prénom des Chaînes de caractères de longueur de 10 caractères avec tous les doublons.
On voit clairement que plus les cordes, la pire des choses et qu'à l'inverse, les plus de doublons, mieux les choses se. Comme mentionné précédemment, les doublons ne pas affecter le plan de mise en cache taille, donc je présume qu'il doit y avoir un processus d'identification en double lors de la construction de la algebrized expression de l'arbre lui-même.
Modifier
Un endroit où cette information est mise à contribution est montré par @Lieven ici
SELECT *
FROM (VALUES ('Lieven1', 1),
('Lieven2', 2),
('Lieven3', 3))Test (name, ID)
ORDER BY name, 1/ (ID - ID)
Parce qu'au moment de la compilation, il peut déterminer que l' Name
colonne a pas de doublons, il saute de la commande par le secondaire 1/ (ID - ID)
expression au moment de l'exécution (le genre dans le plan n'a qu'un seul ORDER BY
de la colonne) et aucune erreur de division par zéro est soulevée. Si des doublons sont ajoutés à la table, alors l'opérateur de tri montre deux ordres de colonnes et l'erreur est générée.