2017-02-13 3 views
0

Tabellengröße 32GB Row zählen 250MWie SQL Server-Abfrage-Leistung

Tabelle DDL

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] 

Ich habe folgende nicht gruppierten Index

merchant_id, order_id 
order_date 

Logisch, die order_id, verbessern merchant_id Mache einen einzigartigen Schlüssel.

Einfache Abfrage wie folgt dauert fast 30 Minuten.

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

Ich habe einige Fragen:

  • Ist PK richtig? Derzeit ist es auf ID-Feld und es wird für nichts verwendet.
  • Werden order_id und merchant_id als PK helfen bei der Leistung?
  • Was sind die idealen Indizes, die ich auf dieser Tabelle haben sollte?
+1

sollten Sie einen Index auf 'Order_Date' erstellen, noch besser, wenn es' Betrag' enthält – Lamak

+1

Was ist der Abfrageplan? – Paurian

+1

Wenn Sie die Größe Ihrer Tabelle und die Anzahl der Zeilen feststellen, sollten Sie wahrscheinlich die von SqlZim vorgeschlagenen Indizes verwenden und Indizes basierend auf dem Umfang des Schreibzugriffs auf diese Tabelle regelmäßig neu erstellen, um die Fragmentierung zu reduzieren. – Paurian

Antwort

0

Was Sie brauchen, ist Index für Datum. Erstellen Sie einen nicht gruppierten Index für das Datum, an dem die Leistung verbessert wird. Die Indexierung ist sehr wichtig für die Abfrageleistung. Anstatt zu starten, sollten Sie einen Index für diese Spalte haben, die in der where-Klausel in Ihrem Fall-Datumsfeld stark verwendet wird.

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

+0

Ich habe bereits einen Index für order_date – sam

1

Ist PK Recht?

Wahrscheinlich. Unter Verwendung dieses Surrogat id für die clustering Schlüssel hält der Speicher-Overhead geringer für alle Indizes, indem eine dünne 4 Byte-Schlüssel anstelle des zusammengesetzten 12-Byte-Schlüssel merchant_id, order_id, order_date oder 8-Byte-Schlüssel merchant_id, order_id

Die Clustering-Schlüssel verwendet, ist, wie jede Index zeigt zurück auf den Rest der Tabelle.

Will machen order_id und merchant_id in der Leistung als PK Hilfe?

Sie müssten die Auswirkung auf alle Abfragen überprüfen, die gegen die Tabelle ausgeführt werden, um zu wissen, ob es helfen würde oder nicht.

Ich würde mich darauf konzentrieren, abdeckende Indizes für Abfragen zu bewerten, die Sie schneller ausführen müssen, und wenn Sie einen Trend finden, wo Sie diese zwei Spalten für die meisten Ihrer Abfragen benötigen, dann vielleicht.

Was sind die idealen Indizes, die ich auf dieser Tabelle haben sollte?

Sie müssen die Abfragen, Ausführungspläne und die aktuelle Indexnutzung überprüfen, um bestimmen zu können, welche Indizes für diese Tabelle benötigt werden.


Da Ihr order_date in Ihrem nicht gruppierten Index nicht die erste Spalte ist, wird der Optimierer höchstwahrscheinlich nicht für Ihr Beispiel Abfrage verwenden.

Auch wenn Sie einen Index auf order_date haben, wird es zurück zu der Tabelle gehen müssen, um die amount zu erhalten. Wenn Sie amount als eingeschlossene Spalte in den Index aufnehmen, wird dies ein überdeckender Index für diese Abfrage, ohne dass Sie zu der Tabelle zurückkehren müssen.

Aus diesem Beispiel Abfrage, Sie so etwas wie diese verwenden könnte einen Index-only Abfrage zu haben, statt einer mit einer Lookup-Tabelle:

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