Sans envisager les index, existe-t-il un moyen de ré-écrire cette requête et d'obtenir le même résultat plus rapide?
select fo.OrderNo, fo.OrderItemSeqNo, COUNT(*)
from Facts.FactBackOrder fo
group by fo.OrderNo, fo.OrderItemSeqNo
having COUNT(*)>1
Quand je la réinscrit comme le suivant, il s'aggrave même.
;WITH R1 AS (
select ROW_NUMBER() OVER (PARTITION BY fo.OrderNo, fo.OrderItemSeqNo ORDER BY fo.OrderNo, fo.OrderItemSeqNo) AS N
,fo.OrderNo
, fo.OrderItemSeqNo
from Facts.FactBackOrder fo
)
SELECT * FROM R1 WHERE N = 2
OU CA:
;WITH R1 AS (
select COUNT_BIG(*) OVER (PARTITION BY fo.OrderNo, fo.OrderItemSeqNo) AS N
,fo.OrderNo
, fo.OrderItemSeqNo
from Facts.FactBackOrder fo
)
SELECT * FROM R1 WHERE N > 1
C'est une table de fait dans une datawarehouse. Les index sont sur l'image ci-dessous.
Une vue indexée dans cette situation utiliserait beaucoup moins d'espace qu'un indice. J'ai cette situation dans une vue indexée similaire - vous pouvez voir le code ci-dessous:
CREATE view [dbo].[VProcessStatus]
WITH SCHEMABINDING
AS
select processstatus,
StatusCount = COUNT_BIG(*)
FROM DBO.tbltaxtransaction
GROUP BY processstatus
GO
GRANT SELECT ON [dbo].[VProcessStatus] TO [mydomain\itdevelopment] AS [dbo]
GO
CREATE UNIQUE CLUSTERED INDEX [IDX_VProcessStatus] ON [dbo].[VProcessStatus]
(
[processstatus] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [pscheme_ProcessStatus]([processstatus])
GO
quand je cherche l'espace utilisé par cette vue et la table sous-jacente:
sp_spaceused 'tbltaxtransaction'
go
sp_spaceused 'VProcessStatus'
go
Je reçois le résultat suivant:
Le seul supplément est que cette vue indexée est partitionnée en fonction des fonctions de schéma de partition et de partition ci-dessous:
CREATE PARTITION SCHEME [pscheme_ProcessStatus] AS PARTITION [pfunc_ProcessStatus] TO ([FG01], [FG02], [FG03], [FG04], [FG05])
GO
CREATE PARTITION FUNCTION [pfunc_ProcessStatus](int) AS RANGE LEFT FOR VALUES (1, 2, 3, 9)
GO
J'ai maintenant quitté Dev à la production. Le fait de la table a 4 183 289 rangées.
SQL Server 2012. Microsoft SQL Server 2012 (SP1) - 11.0.3412.0 (x64) mars 2014 01:25:09 Copyright (c) Microsoft Corporation Enterprise Edition (64 bits) sur Windows NT 6.3 (Build 9600 :)
Mais je ne veux pas utiliser des index de colonne - ces tables sont mises à jour très souvent. Peut-être dans SQL 2014?
le plan de requête original de la requête que je voulais améliorer la performance de l'est:
la seule façon dont j'ai découvert l'amélioration de la requête orginale était d'ajouter un index à la table.
create index idx_FactBackOrder_OrderNo_OrderItemSeqNo
on Facts.FactBackOrder (OrderNo,OrderItemSeqNo) with (online=on)
Quand j'exécute ensuite la requête, je remarque qu'il faut plus de temps que l'original sans index. Le nouveau plan de requête, après avoir créé l'index, est la suivante:
Je dépose immédiatement l'index nouvellement créé:
drop index idx_FactBackOrder_OrderNo_OrderItemSeqNo on Facts.FactBackOrder
Je crée ensuite une vue indexée:
--drop view [dbo].[VfactBackOder]
CREATE view [dbo].[VfactBackOder]
WITH SCHEMABINDING
AS
select fo.OrderNo,
fo.OrderItemSeqNo,
COUNT_BIG(*) as the_number
from Facts.FactBackOrder fo
group by fo.OrderNo, fo.OrderItemSeqNo
GO
créez l'index en cluster pour la vue indexée:
CREATE UNIQUE CLUSTERED INDEX [IDX_VfactBackOder] ON [dbo].[VfactBackOder]
(
OrderNo, OrderItemSeqNo
)
go
Lorsque j'exécute la requête en utilisant la vue indexée nouvellement créée au lieu de la requête d'origine faisant référence aux tables sous-jacentes:
select fo.OrderNo,
fo.OrderItemSeqNo,
fo.the_number
from VfactBackOder fo
where fo.the_number > 1
Je reçois un résultat non satisfaisant. Ensuite, j'ajoute un autre index à la vue:
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[VfactBackOder] ([the_number])
INCLUDE ([OrderNo],[OrderItemSeqNo])
go
Maintenant, la requête vole comme une fusée. Le nouveau plan de requête est:
Et regarder l'espace utilisé par la vue indexée et la table sous-jacente:
sP_SPACEUSE 'FACTSS.FACKBACKER' GO SP_SPACEUSEUSE "VFFFIQULTBODER" Go
la requête fonctionne assez bien, les clients heureux ici. Merci pour tous vos commentaires.