Frage

Ich bin Portierung ein Prozess, der eine MASSIVE CROSS JOIN von zwei Tabellen erstellt. Die resultierende Tabelle enthält 15m Datensätze (sieht aus wie der Prozess ein 30m Cross-Join mit einem 2600 Reihe Tisch und 12000 Reihe Tisch macht und dann hat einige Gruppierung, die es in zwei Hälften geteilt werden). Die Reihen sind relativ schmal - nur 6 Spalten. Es wurde ohne ein Zeichen der Fertigstellung für 5 Stunden ausgeführt wird. Ich habe nur bemerkt, nur die Anzahl Diskrepanz zwischen den guten bekannt und was würde ich für das Kreuz erwarten verbinden, so dass mein Ausgang nicht über die Gruppierung oder deduping, die den Final Table halbieren - dies scheint aber immer noch wie es nicht geht zu vervollständigen Zeit bald.

Zuerst werde ich sehe diese Tabelle, wenn möglich aus dem Prozess zu beseitigen - offensichtlich konnte es durch den Beitritt zu den beiden Tabellen einzeln ausgetauscht werden, aber im Moment habe ich nicht in Sicht überall sonst wird es verwendet <. / p>

Aber da der bestehende Prozess tut es (in weniger Zeit, auf einer weniger leistungsfähige Maschine, mit der FOCUS-Sprache), gibt es Möglichkeiten zur Verbesserung der Leistung der großen CROSS JOINs in SQL Server (2005) (Hardware ist nicht wirklich eine Option, ist dieses Feld ein 64-Bit-8-Wege mit 32-GB RAM)?

Details:

Es ist auf diese Weise in FOCUS geschrieben (Ich versuche, die gleiche Leistung zu erzeugen, die ein CROSS JOIN in SQL ist):

JOIN CLEAR *
DEFINE FILE COSTCENT
  WBLANK/A1 = ' ';
  END
TABLE FILE COSTCENT
  BY WBLANK BY CC_COSTCENT
  ON TABLE HOLD AS TEMPCC FORMAT FOCUS
  END

DEFINE FILE JOINGLAC
  WBLANK/A1 = ' ';
  END
TABLE FILE JOINGLAC
  BY WBLANK BY ACCOUNT_NO BY LI_LNTM
  ON TABLE HOLD AS TEMPAC FORMAT FOCUS INDEX WBLANK

JOIN CLEAR *
JOIN WBLANK IN TEMPCC TO ALL WBLANK IN TEMPAC
DEFINE FILE TEMPCC
  CA_JCCAC/A16=EDIT(CC_COSTCENT)|EDIT(ACCOUNT_NO);
  END
TABLE FILE TEMPCC
  BY CA_JCCAC BY CC_COSTCENT AS COST CENTER BY ACCOUNT_NO
  BY LI_LNTM
  ON TABLE HOLD AS TEMPCCAC
  END

So die erforderliche Ausgabe wirklich ein CROSS JOIN ist (es ist eine leere Spalte von jeder Seite verbinden).

In SQL:

CREATE TABLE [COSTCENT](
       [COST_CTR_NUM] [int] NOT NULL,
       [CC_CNM] [varchar](40) NULL,
       [CC_DEPT] [varchar](7) NULL,
       [CC_ALSRC] [varchar](6) NULL,
       [CC_HIER_CODE] [varchar](20) NULL,
 CONSTRAINT [PK_LOOKUP_GL_COST_CTR] PRIMARY KEY NONCLUSTERED
(
       [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]

CREATE TABLE [JOINGLAC](
       [ACCOUNT_NO] [int] NULL,
       [LI_LNTM] [int] NULL,
       [PR_PRODUCT] [varchar](5) NULL,
       [PR_GROUP] [varchar](1) NULL,
       [AC_NAME_LONG] [varchar](40) NULL,
       [LI_NM_LONG] [varchar](30) NULL,
       [LI_INC] [int] NULL,
       [LI_MULT] [int] NULL,
       [LI_ANLZ] [int] NULL,
       [LI_TYPE] [varchar](2) NULL,
       [PR_SORT] [varchar](2) NULL,
       [PR_NM] [varchar](26) NULL,
       [PZ_SORT] [varchar](2) NULL,
       [PZNAME] [varchar](26) NULL,
       [WANLZ] [varchar](3) NULL,
       [OPMLNTM] [int] NULL,
       [PS_GROUP] [varchar](5) NULL,
       [PS_SORT] [varchar](2) NULL,
       [PS_NAME] [varchar](26) NULL,
       [PT_GROUP] [varchar](5) NULL,
       [PT_SORT] [varchar](2) NULL,
       [PT_NAME] [varchar](26) NULL
) ON [PRIMARY]

CREATE TABLE [JOINCCAC](
       [CA_JCCAC] [varchar](16) NOT NULL,
       [CA_COSTCENT] [int] NOT NULL,
       [CA_GLACCOUNT] [int] NOT NULL,
       [CA_LNTM] [int] NOT NULL,
       [CA_UNIT] [varchar](6) NOT NULL,
 CONSTRAINT [PK_JOINCCAC_KNOWN_GOOD] PRIMARY KEY CLUSTERED
(
       [CA_JCCAC] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
= OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Mit dem SQL-Code:

INSERT  INTO [JOINCCAC]
       (
        [CA_JCCAC]
       ,[CA_COSTCENT]
       ,[CA_GLACCOUNT]
       ,[CA_LNTM]
       ,[CA_UNIT]
       )
       SELECT  Util.PADLEFT(CONVERT(varchar, CC.COST_CTR_NUM), '0',
                                     7)
               + Util.PADLEFT(CONVERT(varchar, GL.ACCOUNT_NO), '0',
                                       9) AS CC_JCCAC
              ,CC.COST_CTR_NUM AS CA_COSTCENT
              ,GL.ACCOUNT_NO % 900000000 AS CA_GLACCOUNT
              ,GL.LI_LNTM AS CA_LNTM
              ,udf_BUPDEF(GL.ACCOUNT_NO, CC.COST_CTR_NUM, GL.LI_LNTM, 'N') AS CA_UNIT
       FROM   JOINGLAC AS GL
       CROSS JOIN COSTCENT AS CC

Je nachdem, wie diese Tabelle anschließend verwendet wird, soll es in der Lage sein, aus dem Prozess eliminiert werden, indem man einfach seinen Wechsel sowohl die ursprünglichen Tabellen verwendet, um ihn zu bauen. Dies ist jedoch ein extrem großer Portierungsaufwand, und ich könnte nicht die Verwendung der Tabelle für einige Zeit finden, so dass ich frage mich, ob es irgendwelche Tricks waren große Tische wie in einer zeitgemäßen Weise CROSS JOINing (zumal die bestehenden Verfahren in FOCUS in der Lage, es schnell zu tun). Auf diese Weise konnte ich die Richtigkeit meines Bau der Ersatz-Abfrage validieren und sie dann später mit Blick ausklammern oder was auch immer.

Ich bin auch unter Berücksichtigung der UDF und String-Manipulation Ausklammern und Durchführen der CROSS erste JOIN ein wenig den Prozess zu brechen.

Die bisherigen Ergebnisse:

Es stellt sich heraus, dass die UDF viel beitragen kann (negativ) auf die Leistung. Aber es scheint auch ein großer Unterschied zwischen einer 15m Reihe zu sein Kreuz verbinden und einem 30m Reihe Kreuz verbinden. Ich habe keine Rechte SHOWPLAN (boo hoo), so kann ich nicht sagen, ob der Plan ist es mit besser oder schlechter ist nach Indizes zu ändern. Ich habe es noch nicht Refactoring, aber erwarte die gesamte Tabelle kurz weg zu gehen.

War es hilfreich?

Lösung

die Abfrage Prüfungs zeigen nur eine Spalte aus einer Tabelle verwendet, und nur zwei Spalten aus der anderen Tabelle verwendet. Aufgrund der sehr geringen Anzahl von Spalten verwendet wird, kann diese Abfrage einfach mit Deck- Indizes verbessert werden:

CREATE INDEX COSTCENTCoverCross ON COSTCENT(COST_CTR_NUM)
CREATE INDEX JOINGLACCoverCross ON JOINGLAC(ACCOUNT_NO, LI_LNTM)

Hier sind meine Fragen zur weiteren Optimierung:

Wenn Sie die Abfrage in Query Analyzer setzen und Whack die „Show geschätzten Ausführungsplan“ Taste, wird es eine grafische Darstellung zeigen, was es tun wird.

Join-Typ: Es sollte eine verschachtelte Schleife dort beitreten wird. (Die anderen Optionen sind fusionieren verbinden und Hashverknüpfung). Wenn Sie verschachtelte Schleife zu sehen, dann ok. Wenn Sie sehen, verschmelzen beitreten oder Hashverknüpfung, lassen Sie es uns wissen.

Reihenfolge der Tabellenzugriff: Gehen den ganzen Weg nach oben und bewegen den ganzen Weg nach rechts. Der erste Schritt soll eine Tabelle zugreifen. Welche Tabelle ist, dass und welche Methode verwendet wird (Index-Scan, gruppierten Index-Scan)? Welche Methode wird verwendet, um die andere Tabelle zuzugreifen?

Parallelismus: Sie sollten die kleinen jaggedy Pfeile auf fast alle Symbole im Plan angezeigt, dass Parallelität verwendet wird. Wenn Sie dies nicht sehen, es ist ein großes Problem!

Das udf_BUPDEF mich betrifft. Ist es aus zusätzlichen Tabellen lesen? Util.PADLEFT betrifft mich weniger, aber immer noch .. was ist es? Wenn es nicht ein Datenbankobjekt ist, dann erwägen, mit dieser statt:

RIGHT('z00000000000000000000000000' + columnName, 7)

Gibt es irgendwelche Trigger auf JOINCCAC? Wie wäre es Indizes? Mit einem Einsatz dieses große, werden Sie alle Trigger und Indizes für diese Tabelle löschen wollen.

Andere Tipps

Weiter auf, was andere ein Wort, Funktionen DB, die Abfragen enthalten, die immer in einem ausgewählten verwendet werden, machte meine Abfragen extrem langsam. Aus der Spitze von meinem Kopf, ich glaube, dass ich eine Abfrage hatte in 45 Sekunden lief, dann entfernte ich die Funktion, und dann Ergebnis 0 Sekunden waren:)

So überprüfen udf_BUPDEF wird keine Anfragen zu tun.

Überwinden Sie die Abfrage es ein einfaches einfaches Kreuz verbinden zu machen.


   SELECT  CC.COST_CTR_NUM, GL.ACCOUNT_NO
              ,CC.COST_CTR_NUM AS CA_COSTCENT
              ,GL.ACCOUNT_NO AS CA_GLACCOUNT
              ,GL.LI_LNTM AS CA_LNTM
-- I don't know what is BUPDEF doing? but remove it from the query for time being
--              ,udf_BUPDEF(GL.ACCOUNT_NO, CC.COST_CTR_NUM, GL.LI_LNTM, 'N') AS CA_UNIT
       FROM   JOINGLAC AS GL
       CROSS JOIN COSTCENT AS CC

Sehen Sie, wie gut das einfache Kreuz verbinden? (Ohne irgendwelche Funktionen auf sie angewendet wird)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top