Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pb perf avec Vues Distribuées Partitionnées

2 réponses
Avatar
Sébastien Carriot
Bonjour,

J'ai des problèmes de performances avec des vues partionnées et distribuées.
J'ai deux serveurs (Server1 et Server2) sur lesquels j'ai deux tables de
même structure, avec contrainte CHECK sur la date. L'une comporte des
données de 2000 à 2003 et l'autre sur 2004 (et plus pour plus tard).
J'ai ensuite une vue sur un des deux serveurs (peu importe lequel, le
résultat est le même) qui lie par une "UNION ALL" toutes les données des
deux tables.

Le problème :
- (1) Un SELECT à partir du server2 sur la table du Server2 pour des données
2004 = instantané
- (2) Un SELECT à partir du server2 sur la table du Server1 (étant donc en
serveur lié) pour des données 2003 = instantané (ce n'est donc pas un
problème de serveur lié qui marche très bien dans de nombreux autres cas)
- (3) Un SELECT à partir du server2 dans ma vue sur des données 2004 =
instantané
- (4) Un SELECT à partir du server2 dans ma vue sur des données 2003 = 1
minute !! (même s'il n'y a qu'une ligne ou avec les même données que le cas
numéro 2)

J'ai remarqué dans le plan d'exécution de l'analyseur de requête qu'il tente
dans ce cas d'accéder aux deux serveurs alors que les contraintes CHECK
devraient l'en empêcher puisqu'il n'y a que des données 2003 présentes donc
sur le server1 seulement.

Merci d'avance pour toutes vos remarques qui seront les bienvenues. Cela
fait maintenant 1 semaine que je suis sur le problème.

Voilà la structure précise de mes objets :


Sur le Server1 :

CREATE TABLE [Achats] (
[Client] [int] NOT NULL ,
[DateAchat] [smalldatetime] NOT NULL ,
[Montant] [int] NOT NULL ,
CONSTRAINT [IX_Achats] UNIQUE CLUSTERED
(
[Client],
[DateAchat],
[Montant]
) ON [PRIMARY] ,
CONSTRAINT [CK_Achats] CHECK ([DateAchat] <= '31/12/2003')
) ON [PRIMARY]


Sur le Server2 :

CREATE TABLE [Achats] (
[Client] [int] NOT NULL ,
[DateAchat] [smalldatetime] NOT NULL ,
[Montant] [int] NOT NULL ,
CONSTRAINT [IX_Achats] UNIQUE CLUSTERED
(
[Client],
[DateAchat],
[Montant]
) ON [PRIMARY] ,
CONSTRAINT [CK_Achats] CHECK ([DateAchat] >= '01/01/2004')
) ON [PRIMARY]


Sur le Server2 (ou 1) :

CREATE VIEW dbo.vueAllAchats
AS
SELECT Client, DateAchat, Montant
FROM dbo.Achats
UNION ALL
SELECT Client, DateAchat, Montant
FROM Server1.BDDAchats2003.dbo.Achats


Rappel du problème en détail :
- (1) Sur Server2 : SELECT * FROM Achats WHERE DateAchat = '01/01/2004' =
instantané
- (2) Sur Server2 : SELECT * FROM Server1.BDDAchats2003.dbo.Achats WHERE
DateAchat = '31/12/2003' = instantané
- (3) Sur Server2 : SELECT * FROM vueAllAchats WHERE DateAchat =
'01/01/2004' = instantané
- (4) Sur Server2 : SELECT * FROM vueAllAchats WHERE DateAchat =
'31/12/2003' = 1 minute !!

Encore merci !

Sébastien

2 réponses

Avatar
Med Bouchenafa
En supposant que toutes les conditions requises par une vue partitionnée soient effectivement respectées, je te propose
de réecrire la condition CHECK sur la colonne date avec une syntaxe ANSI CHECK ([DateAchat] <= '20031231' et d'autre
part, d'essayer en changeant le type SMALLDATETIME en DATETIME.
Tiens nous au courant de tes évolutions, c'est la deuxième fois que je vois ce problème

Bien cordialement
Med Bouchenafa




"Sébastien Carriot" a écrit dans le message de news:
Bonjour,

J'ai des problèmes de performances avec des vues partionnées et distribuées.
J'ai deux serveurs (Server1 et Server2) sur lesquels j'ai deux tables de
même structure, avec contrainte CHECK sur la date. L'une comporte des
données de 2000 à 2003 et l'autre sur 2004 (et plus pour plus tard).
J'ai ensuite une vue sur un des deux serveurs (peu importe lequel, le
résultat est le même) qui lie par une "UNION ALL" toutes les données des
deux tables.

Le problème :
- (1) Un SELECT à partir du server2 sur la table du Server2 pour des données
2004 = instantané
- (2) Un SELECT à partir du server2 sur la table du Server1 (étant donc en
serveur lié) pour des données 2003 = instantané (ce n'est donc pas un
problème de serveur lié qui marche très bien dans de nombreux autres cas)
- (3) Un SELECT à partir du server2 dans ma vue sur des données 2004 > instantané
- (4) Un SELECT à partir du server2 dans ma vue sur des données 2003 = 1
minute !! (même s'il n'y a qu'une ligne ou avec les même données que le cas
numéro 2)

J'ai remarqué dans le plan d'exécution de l'analyseur de requête qu'il tente
dans ce cas d'accéder aux deux serveurs alors que les contraintes CHECK
devraient l'en empêcher puisqu'il n'y a que des données 2003 présentes donc
sur le server1 seulement.

Merci d'avance pour toutes vos remarques qui seront les bienvenues. Cela
fait maintenant 1 semaine que je suis sur le problème.

Voilà la structure précise de mes objets :


Sur le Server1 :

CREATE TABLE [Achats] (
[Client] [int] NOT NULL ,
[DateAchat] [smalldatetime] NOT NULL ,
[Montant] [int] NOT NULL ,
CONSTRAINT [IX_Achats] UNIQUE CLUSTERED
(
[Client],
[DateAchat],
[Montant]
) ON [PRIMARY] ,
CONSTRAINT [CK_Achats] CHECK ([DateAchat] <= '31/12/2003')
) ON [PRIMARY]


Sur le Server2 :

CREATE TABLE [Achats] (
[Client] [int] NOT NULL ,
[DateAchat] [smalldatetime] NOT NULL ,
[Montant] [int] NOT NULL ,
CONSTRAINT [IX_Achats] UNIQUE CLUSTERED
(
[Client],
[DateAchat],
[Montant]
) ON [PRIMARY] ,
CONSTRAINT [CK_Achats] CHECK ([DateAchat] >= '01/01/2004')
) ON [PRIMARY]


Sur le Server2 (ou 1) :

CREATE VIEW dbo.vueAllAchats
AS
SELECT Client, DateAchat, Montant
FROM dbo.Achats
UNION ALL
SELECT Client, DateAchat, Montant
FROM Server1.BDDAchats2003.dbo.Achats


Rappel du problème en détail :
- (1) Sur Server2 : SELECT * FROM Achats WHERE DateAchat = '01/01/2004' > instantané
- (2) Sur Server2 : SELECT * FROM Server1.BDDAchats2003.dbo.Achats WHERE
DateAchat = '31/12/2003' = instantané
- (3) Sur Server2 : SELECT * FROM vueAllAchats WHERE DateAchat > '01/01/2004' = instantané
- (4) Sur Server2 : SELECT * FROM vueAllAchats WHERE DateAchat > '31/12/2003' = 1 minute !!

Encore merci !

Sébastien




Avatar
Sébastien Carriot
Merci Med, ça fonctionne !
Je n'ai pas réussi à utiliser le ANSI CHECK qui est refusé dans ma création
de table mais le changement en DATETIME fonctionne. L seul problème dans mon
cas est que la table est énorme (plus de 40 Go) en quelques champs seulement
donc 4 octect de plus par ligne n'est pas très envisageable. J'ai donc
transformé le champ DateAchat en INT avec un stockage sous la forme 20040101
etc. Ce n'est pas très propre mais ça marche très bien.
Encore merci.
Sébastien

"Med Bouchenafa" a écrit dans le message de
news:%
En supposant que toutes les conditions requises par une vue partitionnée


soient effectivement respectées, je te propose
de réecrire la condition CHECK sur la colonne date avec une syntaxe ANSI


CHECK ([DateAchat] <= '20031231' et d'autre
part, d'essayer en changeant le type SMALLDATETIME en DATETIME.
Tiens nous au courant de tes évolutions, c'est la deuxième fois que je


vois ce problème

Bien cordialement
Med Bouchenafa




"Sébastien Carriot" a écrit dans le message de


news:
> Bonjour,
>
> J'ai des problèmes de performances avec des vues partionnées et


distribuées.
> J'ai deux serveurs (Server1 et Server2) sur lesquels j'ai deux tables de
> même structure, avec contrainte CHECK sur la date. L'une comporte des
> données de 2000 à 2003 et l'autre sur 2004 (et plus pour plus tard).
> J'ai ensuite une vue sur un des deux serveurs (peu importe lequel, le
> résultat est le même) qui lie par une "UNION ALL" toutes les données des
> deux tables.
>
> Le problème :
> - (1) Un SELECT à partir du server2 sur la table du Server2 pour des


données
> 2004 = instantané
> - (2) Un SELECT à partir du server2 sur la table du Server1 (étant donc


en
> serveur lié) pour des données 2003 = instantané (ce n'est donc pas un
> problème de serveur lié qui marche très bien dans de nombreux autres


cas)
> - (3) Un SELECT à partir du server2 dans ma vue sur des données 2004 > > instantané
> - (4) Un SELECT à partir du server2 dans ma vue sur des données 2003 = 1
> minute !! (même s'il n'y a qu'une ligne ou avec les même données que le


cas
> numéro 2)
>
> J'ai remarqué dans le plan d'exécution de l'analyseur de requête qu'il


tente
> dans ce cas d'accéder aux deux serveurs alors que les contraintes CHECK
> devraient l'en empêcher puisqu'il n'y a que des données 2003 présentes


donc
> sur le server1 seulement.
>
> Merci d'avance pour toutes vos remarques qui seront les bienvenues. Cela
> fait maintenant 1 semaine que je suis sur le problème.
>
> Voilà la structure précise de mes objets :
>
>
> Sur le Server1 :
>
> CREATE TABLE [Achats] (
> [Client] [int] NOT NULL ,
> [DateAchat] [smalldatetime] NOT NULL ,
> [Montant] [int] NOT NULL ,
> CONSTRAINT [IX_Achats] UNIQUE CLUSTERED
> (
> [Client],
> [DateAchat],
> [Montant]
> ) ON [PRIMARY] ,
> CONSTRAINT [CK_Achats] CHECK ([DateAchat] <= '31/12/2003')
> ) ON [PRIMARY]
>
>
> Sur le Server2 :
>
> CREATE TABLE [Achats] (
> [Client] [int] NOT NULL ,
> [DateAchat] [smalldatetime] NOT NULL ,
> [Montant] [int] NOT NULL ,
> CONSTRAINT [IX_Achats] UNIQUE CLUSTERED
> (
> [Client],
> [DateAchat],
> [Montant]
> ) ON [PRIMARY] ,
> CONSTRAINT [CK_Achats] CHECK ([DateAchat] >= '01/01/2004')
> ) ON [PRIMARY]
>
>
> Sur le Server2 (ou 1) :
>
> CREATE VIEW dbo.vueAllAchats
> AS
> SELECT Client, DateAchat, Montant
> FROM dbo.Achats
> UNION ALL
> SELECT Client, DateAchat, Montant
> FROM Server1.BDDAchats2003.dbo.Achats
>
>
> Rappel du problème en détail :
> - (1) Sur Server2 : SELECT * FROM Achats WHERE DateAchat = '01/01/2004'


> > instantané
> - (2) Sur Server2 : SELECT * FROM Server1.BDDAchats2003.dbo.Achats WHERE
> DateAchat = '31/12/2003' = instantané
> - (3) Sur Server2 : SELECT * FROM vueAllAchats WHERE DateAchat > > '01/01/2004' = instantané
> - (4) Sur Server2 : SELECT * FROM vueAllAchats WHERE DateAchat > > '31/12/2003' = 1 minute !!
>
> Encore merci !
>
> Sébastien
>
>