Wird sich die Änderung der Spaltenreihenfolge in GROUP BY auf die Leistung auswirken?

7

Ich habe eine SQL-Abfrage wie folgt:

SELECT A, B, (CASE WHEN C=0 THEN 0 ELSE 1 END), COUNT(D)
FROM SomeTable
GROUP BY A, B, (CASE WHEN C=0 THEN 0 ELSE 1 END)

Bei einem großen Datensatz wird der tatsächliche Ausführungsplan die meiste Zeit einem Knoten zugeordnet, der der logischen Operation Aggregate und der physischen Operation HashMatch entspricht .

Wird sich das Ändern der Reihenfolge, in der die Spalten und Bedingungen in der GROUP BYListe aufgeführt sind, auf die Leistung auswirken?

scharfer Zahn
quelle

Antworten:

7

Trotz der Aussagen in der MSDN-Dokumentation ist dies für GROUP BYAbfragen nicht wichtig .

Sie können es hier testen unter: SQL-Fiddle-Test (SQL-Server 2012)

CREATE TABLE test
( id INT IDENTITY(1,1)
, a  INT NOT NULL
, b  INT NOT NULL
, c  INT NOT NULL
, d  INT NOT NULL
, PRIMARY KEY (id)
) ;

CREATE NONCLUSTERED INDEX a_b_c_include_d_index
    ON test (a, b, c)
    INCLUDE (d) ;

INSERT INTO test
(a, b, c, d)
VALUES
 ... some 50K rows

Die Fragen:

SELECT COUNT(*) AS num
     , MIN(cnt) AS min_count
     , MAX(cnt) AS max_count
     , MIN(min_d) AS min_min_d
     , MAX(min_d) AS max_min_d
     , MIN(max_d) AS min_max_d
     , MAX(max_d) AS max_max_d
FROM
  ( SELECT a
         , b
         , c
         , COUNT(d) AS cnt
         , MIN(d) AS min_d
         , MAX(d) AS max_d
    FROM test 
    GROUP BY a, b, c             --- or with:  `GROUP BY b, a, c`
  ) AS grp ;

den gleichen Ausführungsplan erstellen:

Ausführungsplan

MICROSOFT SQL SERVER 2005 XML SHOWPLAN
SELECT
Compute Scalar
Cost: 0%
Stream Aggregate
(Aggregate)
Cost: 0%
Compute Scalar
Cost: 10%
Stream Aggregate
(Aggregate)
Cost: 10%
Index Scan
[a_b_c_include_d_index].[test]
Cost: 89%

Wenn Sie diese Gruppe nun ändern in:

    GROUP BY a, b, c
      WITH ROLLUP

es macht einen Unterschied und es erzeugt unterschiedliche Ausführungspläne (und natürlich unterschiedliche Ergebnismengen). Zumindest in diesem SQL-Fiddle-Test wird der Index jedoch weiterhin verwendet. Im Fall einer nicht übereinstimmenden Reihenfolge werden die Daten aus dem Index abgerufen, es muss jedoch eine Zwischensortierung durchgeführt werden (um die Rollup-Werte zu berechnen).

ypercubeᵀᴹ
quelle
2

Ja, wenn Sie einen Index haben, der diese Spalten abdeckt.

Laut der Dokumentation bei MSDN :

Im Kontext von mehrspaltigen Indizes müssen die Spalten ORDER-BY oder GROUP-BY mit dem Präfixsatz der Indexspalten in der genauen Reihenfolge übereinstimmen, damit ORDER-BY oder GROUP-BY einen bestimmten Index berücksichtigen. Zum Beispiel der Index

CREATE INDEX Emp_Name ON Employees ("Last Name" ASC, "First Name" ASC) 

kann helfen, die folgenden Abfragen zu optimieren:

... ORDER BY / GROUP BY "Last Name" ...
... ORDER BY / GROUP BY "Last Name", "First Name" ...

Es wird nicht helfen, zu optimieren:

... ORDER BY / GROUP BY "First Name" ...
... ORDER BY / GROUP BY "First Name", "Last Name" ...
Jason
quelle
2
GROUP BY "First Name", "Last Name"ist das gleiche wie GROUP BY "Last Name", "First Name"nein? Nach WHERE und ON spielt die Reihenfolge keine Rolle. Für ORDER BY ist dies der Fall
gbn
Die Dokumentation, auf die Sie verlinken, ist für SQL Server Compact 4.0
Martin Smith
1
@MartinSmith: Zu Jasons Gunsten hat die Dokumentation für die Version 2008 dasselbe.
Ypercubeᵀᴹ
@ypercube - Link? Das Klicken auf die Auswahl "Andere Versionen" scheint für mich nicht zu funktionieren. Ich komme immer noch zu einem Artikel, in dem SQL Server Compact speziell behandelt wird. Keine Ahnung, ob es für die kompakten Versionen gilt oder nicht, aber vielleicht haben sie einen primitiveren Optimierer.
Martin Smith
@ MartinSmith: Oh, du hast recht, ja, ich habe diese Zeile verpasst. Können wir also davon ausgehen, dass dies von der Version des SQL-Servers abhängt? Wenn ja, was ist mit Azure? Ich kann keine Dokumentation finden.
Ypercubeᵀᴹ