2017-02-13 1 views
0

Taille de la table 32Go compte Ligne 250MComment améliorer les performances des requêtes SQL Server

Tableau LDD

CREATE TABLE Orders 
(
    ID [int] IDENTITY(1,1) NOT NULL, 
    server [varchar](50) NULL, 
    server_id [int] NOT NULL, 
    merchant_id [int] NOT NULL, 
    order_id [int] NOT NULL, 
    customer_id [int] NOT NULL, 
    customer_name [varchar](50) NULL, 
    [amount] [money] NULL, 
    order_date [smalldatetime] NULL, 
    ship_date [smalldatetime] NULL, 
    order_status [varchar](50) NULL,  
    custom_field_1 [varchar](50) NULL, 
    custom_field_2 [varchar](50) NULL, 
    custom_field_3 [varchar](50) NULL, 
    custom_field_4 [varchar](50) NULL, 
    created_at [datetime] NULL 

    CONSTRAINT [PK_Orders] 
     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] 
) ON [PRIMARY] 

Je suit index non cluster

merchant_id, order_id 
order_date 

Logiquement, le order_id, merchant_id faire une clé unique.

requête simple comme ci-dessous prend près de 30 minutes.

select 
    sum(amount) 
from 
    Orders 
where 
    Order_Date >= getdate() - 7 

J'ai quelques questions:

  • est le PK droit? Actuellement, il est sur le champ d'identification et il n'est pas utilisé pour quoi que ce soit.
  • Est-ce que faire order_id et merchant_id comme aide PK dans la performance?
  • Quels sont les indices idéaux que je devrais avoir sur cette table?
+1

vous devriez créer un index sur 'Order_Date', encore mieux s'il contient' amount' – Lamak

+1

Quel est le plan de requête? – Paurian

+1

En notant la taille de votre table et le nombre de lignes, vous voudrez probablement prendre ce que SqlZim a suggéré et reconstruire les index périodiquement en fonction de la quantité de trafic écrivant à cette table pour réduire la fragmentation. – Paurian

Répondre

0

Ce dont vous avez besoin est un index sur la date. Créer un index non clusterisé sur la date, il aidera dans la performance. L'indexation est très importante dans les performances des requêtes. Pour commencer, vous devriez avoir un index sur ces colonnes qui sont fortement utilisées dans la clause where du champ de la date de votre cas.

https://www.simple-talk.com/sql/learn-sql-server/sql-server-index-basics/

+0

J'ai déjà un index sur order_date – sam

1

Est ce que le PK droit?

Probablement. L'utilisation de ce substitut id pour le regroupement clé maintient le stockage aérien plus faible pour tous les index en utilisant une mince clé de 4 octets au lieu de la clé composite 12 d'octets de merchant_id, order_id, order_date touche ou 8 octets de merchant_id, order_id

La clé de cluster est la façon dont chaque index pointe vers le reste de la table.

Est-ce que faire order_id et MERCHANT_ID comme aide PK dans la performance?

Vous devriez examiner l'impact sur toutes les requêtes qui s'exécutent sur la table pour savoir si cela aiderait ou non. Je me concentrerais sur l'évaluation des index de couverture pour les requêtes que vous devez exécuter plus rapidement, et si vous trouvez une tendance où vous avez besoin de ces deux colonnes pour la plupart de vos requêtes, alors peut-être.

Quels sont les indices idéaux que je devrais avoir sur cette table?

Vous devez examiner les requêtes, les plans d'exécution et l'utilisation actuelle de l'index pour pouvoir déterminer les index dont vous avez besoin pour cette table.


Depuis votre order_date n'est pas la première colonne de l'index non cluster, l'optimiseur sera très probablement pas l'utiliser pour votre exemple de requête.

Même si vous avez un index sur order_date, il va falloir revenir à la table pour obtenir le amount. Si vous incluez amount dans une colonne incluse dans l'index, il deviendra un index de couverture pour cette requête, sans avoir besoin de revenir à la table.

Pour cet exemple requête, vous pouvez utiliser quelque chose comme ça pour avoir une requête d'index seulement, au lieu d'une avec une recherche de table:

create nonclustered index ix_Orders (Order_Date) include (amount);