2009-09-01 7 views
9

J'ai plusieurs bases de données sur une seule instance de SQL Server 2005. J'ai créé un synonyme sur une base de données pour accéder à une table sur une autre base de données et lors de l'écriture de mes requêtes, je voudrais utiliser un index spécifique, cependant, lors de l'évaluation du plan d'exécution, il ne semble pas l'utiliser. Si j'écris la requête pour accéder explicitement à la base de données, cela fonctionne, mais je n'arrive pas à l'obtenir en utilisant un synonyme. Par exemple:Syntaxe de table SQL Server avec index

select * 
from testdb..testtable with (index(testindex)) 

|--Nested Loops(Inner Join, OUTER REFERENCES:([testdb].[dbo].[testtable].[id])) 
    |--Index Scan(OBJECT:([testdb].[dbo].[testtable].[testindex])) 
    |--Clustered Index Seek(OBJECT:([testdb].[dbo].[testtable].[PK_testtable]), SEEK:([testdb].[dbo].[testtable].[id]=[testdb].[dbo].[testtable].[id]) LOOKUP ORDERED FORWARD) 

ne donne pas le même plan d'exécution que

select * 
from testdb_synonym with (index(testindex)) 

|--Clustered Index Scan(OBJECT:([testdb].[dbo].[testtable].[PK_testtable])) 

Est-ce une limitation des synonymes ou est-il quelque chose de spécifique que je dois faire pour que cela fonctionne?

+1

Pourriez-vous s'il vous plaît publier des plans sous-jacents pour les deux requêtes? Il suffit d'exécuter 'SET SHOWPLAN_TEXT ON GO SELECT ...' – Quassnoi

+0

J'ai mis à jour la description pour inclure le plan d'exécution ... –

Répondre

1

J'ai testé la même chose et il semble que l'optimiseur de requête ignore cet indice lorsqu'il est effectué via un synonyme. Les détails sont que j'ai fait un select * contre une table arbitraire avec un indice indice pour utiliser un index non-cluster. Sans le synonyme, il effectue une recherche de signet/une jointure de boucle imbriquée. Avec cela, il effectue un scan de table. Comme il n'y a pas d'options sur la syntaxe create synonym, je peux seulement supposer que l'indice hint est ignoré. Aucun détail dans BOL pour savoir pourquoi. Je le qualifierais de «caractéristique».

+0

J'espérais que ce ne serait pas le cas ... Il a été présenté comme une fonctionnalité d'aliasing avec une partie de la en profiter pour simplifier la notation par points.Je peux comprendre si cela va à l'encontre d'un serveur distant, mais si c'est un serveur local, j'espérais que ce serait assez intelligent pour profiter des avantages inhérents. –

0

Avez-vous besoin de l'indice dans votre étui? Les recommandations MS sont d'éviter les indices si cela est possible car cela peut invalider un plan plus optimisé. Même si elle est optimisée aujourd'hui elle peut être inefficiens demain en raison de chargement de données etc.

J'ai essayé d'utiliser un synonyme sans l'indice dans SQL Server 2008 et j'ai obtenu le même plan d'exécution avec le synonyme qu'avec le nom complet (database.schema.table). J'ai même essayé d'utiliser le synonyme avec un indicateur d'index et forcé avec succès une recherche d'index non cluster (et une recherche de clé pour obtenir le reste des données), et j'obtiens le même plan d'exécution avec un nom complet.

Vos statistiques sont-elles mises à jour? Avez-vous un index sélectif ou est-ce que SQL Server pense qu'il est plus efficace d'utiliser une analyse de table.

1

WITH INDEX Les indications semblent être ignorées pour les synonymes.

CREATE SYNONYM syn_master FOR master 

SELECT * 
FROM syn_master WITH (INDEX (wow_i_can_write_everything_here)) 

compile, et fonctionne Allright malgré le fait que je n'ai pas un index nommé wow_i_can_write_everything_here dans mon schéma.

+0

Ce n'est plus vrai pour SQL Server 2008 R2. BTW: vous créez un synonyme à la base de données principale, je ne pense pas que cela fonctionnerait (sélectionnez * from master ??). –

5

C'est un bug que Microsoft a fixe: voir MS KB 963684

Dans Microsoft SQL Server 2005, vous créer un synonyme pour une table. Vous exécutez une requête sur le synonyme. La requête utilise l'indicateur INDEX optimizer pour forcer un index. Si vous examinez le plan d'exécution généré pour la requête, , le plan d'exécution peut ne pas utiliser l'index forcé.

Questions connexes