2013-09-25 6 views
0

Nous avons un problème de performances avec notre configuration SQL Server 2012 Enterprise que je ne peux pas expliquer et j'espère que vous avez une idée.Problème de performances SQL Server 2012

Nous avons une table de faits avec un groupe de colonnes int que nous regroupons ainsi qu'une table de dimension de région.

C'est la structure de notre table fait:

  • regionId (int)
  • revenus (Décimal 10,2)
  • orderIntake (décimal 10,2)

Et Voici la structure de notre tableau de dimensions:

  • worldR ÉGION (varchar (100) 9
  • grappe (varchar (100))
  • pays (varchar (100))
  • regionId (int)

La table de faits et la table de dimension sont reliés par l'intermédiaire une INNER JOIN sur les colonnes regionId. La performance de ceci est assez bonne tant que nous ne limitons pas les pays.

E.g.

SELECT SUM(revenue) FROM factTable f INNER JOIN regionDim r ON f.regionId=r.regionId

est rapide (< 1 sec).

Cependant

SELECT SUM(revenue) FROM factTable f INNER JOIN regionDim r ON f.regionId=r.regionId WHERE r.country IN ('France','Germany')

est assez lent (> 8 sec) pour environ 500k enregistrements.

Nous avons les indizes suivantes en place:

  • columnstore Index sur la table de fait sur la colonne regionId
  • index cluster sur la table de dimension (regionId, pays, cluster, worldRegion)

Y a-t-il quelque chose que nous pouvons changer d'un point de vue de l'index ou de la structure globale?

+2

Avez-vous regardez le plan de requête? Que dit-il des index utilisés? – cdoubleplusgood

Répondre

2

L'ordre des colonnes dans l'index de la table de variation ne permet pas d'utiliser cet index dans la clause where de la 2ème requête. En effet, les lignes sont indexées par la première colonne d'index (regionId), puis par la seconde (pays) et ainsi de suite. Utiliser seulement la 2ème colonne est comme utiliser un annuaire téléphonique lorsque vous recherchez quelqu'un par le prénom seulement. Essayez de placer un index séparé dans la colonne country et de voir si les performances s'améliorent.

0

Sans le plan d'exécution, il est difficile de voir quel est le problème. Je me demande si vous extrayez d'abord les RegionID de la table de dimension dans une expression de table ou une table temporaire et puis les utilisez contre la table de faits si elle fonctionnera plus rapidement.

Peut-être ceci:

WITH regionIDcte AS 
(
SELECT regionId 
FROM regionDim 
WHERE country IN ('France','Germany') 
) 
SELECT SUM(revenue) 
FROM factTable f 
WHERE EXISTS 
    (
    SELECT * 
    FROM regionIDcte x 
    WHERE f.regionId = f.regionId 
);