J'ai la requête ci-dessous:
CREATE INDEX IX_SLA_SLAName_FK_SLA_Process_IsActive ON dbo.SLA (SLAName, FK_SLA_Process, IsActive) INCLUDE (SLATimeInSeconds)
Et voici mon index pour cette table SLA .
SELECT PrimaryKey FROM dbo.SLA WHERE SLAName = @input AND FK_SLA_Process = @input2 AND IsActive = 1
Cependant, la colonne SLAName est unique et a donc une contrainte / index unique. Mon index créé est-il excessif? En ai-je encore besoin ou est-ce que SQL Server utilisera l'index créé dans la colonne unique SLAName?
3 Réponses :
Ce serait un "overkill" si votre index était uniquement sur SLAName
, mais vous commandez également par FK_SLA_Process
et IsActive
donc les requêtes qui ont besoin de colonnes bénéficieront davantage de votre index et moins si vous n'aviez que l'unique.
Donc, pour une requête comme celle-ci:
SELECT SLATimeInSeconds FROM dbo.SLA WHERE SLAName = 'SomeName'
Les deux index produiront les mêmes résultats et il n'y aurait aucun intérêt dans le vôtre. Mais pour des requêtes comme:
SELECT PrimaryKey FROM dbo.SLA WHERE SLAName = 'SomeName' AND FK_SLA_Process = 'Some Value'
Ou
SELECT PrimaryKey FROM dbo.SLA WHERE SLAName = 'SomeName'
Votre index sera meilleur que l'unique (le 2ème exemple est un couvrant l'index).
Vous devriez inspecter le type de SELECT
que vous faites à cette table et décider si vous en avez besoin ou non. Gardez à l'esprit que le fait d'avoir de nombreux index peut accélérer les sélections mais ralentir les insertions, les mises à jour et les suppressions.
En supposant que vous ayez une telle déclaration de table:
UNIQUE NONCLUSTERED ( [SLAName] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
Sous le capot, nous avons deux index:
SELECT s.ID FROM dbo.SLA s WHERE s.SLAName = 'test' AND s.fk_SLA = 1 AND s.IsActive = 1
Donc, cette requête aura une recherche d'index et a un plan optimal:
SELECT s.ID FROM dbo.SLA s WHERE s.SLAName = 'test'
Son plan de requête indique une recherche d'index car nous recherchons par index UNIQUE NONCLUSTERED ([SLAName] ASC) code > et n'utilisez pas d'autres colonnes dans l'instruction
WHERE
:
Mais si vous ajoutez un supplément paramètres dans WHERE
:
CREATE TABLE [dbo].[SLA]( [ID] [int] NOT NULL, [SLAName] [varchar](50) NOT NULL, [fk_SLA] [int] NULL, [IsActive] [tinyint] NULL, PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], UNIQUE NONCLUSTERED ( [SLAName] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
Le plan d'exécution aura une recherche supplémentaire:
La recherche se produit lorsque l'index ne possède pas les informations nécessaires. Le moteur de requête SQL doit sortir de la structure de données d'index UNIQUE NONCLUSTERED
pour trouver les données des colonnes fk_SLA
et IsActive
dans votre table SLA .
Votre index est donc excessif car vous avez un index UNIQUE NONCLUSTERED
:
CREATE TABLE SLA ( ID INT PRIMARY KEY, SLAName VARCHAR(50) NOT NULL UNIQUE, fk_SLA INT, IsActive TINYINT )
Si la colonne SLAName
est unique
et si elle a une contrainte unique
, toute requête qui ne renvoie qu'une ou 0 ligne (toutes les requêtes avec une recherche par point qui inclut la condition SLAName = 'SomeName'
) utilisera l ' index unique
et fera (au maximum) une recherche code> dans la table de base.
À moins que vos requêtes ne comportent une recherche par plage comme SLAName comme "SomeName%"
, il n'est pas nécessaire de couvrir l'index car la recherche d'index + 1 recherche est presque la même chose que seulement recherche d'index, et il n'est pas nécessaire de gaspiller de l'espace / maintenir un autre index pour un gain de performances aussi misérable.
Vous devriez vous renseigner sur la «couverture des index» pour voir quand cela peut être utile pour améliorer les performances des requêtes. Il est impossible de dire si cela aidera dans votre base de données sans plus d'informations. Vous pouvez commencer par lire cet article: mssqltips.com/sqlservertip / 3511 /…