Frage

Ich benutze Sybase 12.5.3 (ASE);Ich bin neu bei Sybase, obwohl ich schon ziemlich intensiv mit MSSQL gearbeitet habe.Ich stoße auf ein Szenario, in dem eine gespeicherte Prozedur wirklich sehr langsam ist.Ich habe das Problem auf einen einzelnen SELECT-Befehl für eine relativ große Tabelle zurückgeführt.Das Ändern dieser Anweisung verbessert die Leistung der Prozedur erheblich (und das Zurücksetzen verlangsamt sie drastisch).d. h. der SELECT stmt ist definitiv der Schuldige).

-- Sybase optimizes and uses multi-column index... fast!<br>
SELECT ID,status,dateTime
FROM myTable
WHERE status in ('NEW','SENT')
ORDER BY ID

-- Sybase does not use index and does very slow table scan<br>
SELECT ID,status,dateTime
FROM myTable
WHERE status in (select status from allowableStatusValues)
ORDER BY ID

Der obige Code ist eine angepasste/vereinfachte Version des tatsächlichen Codes.Beachten Sie, dass ich bereits versucht habe, die Prozedur neu zu kompilieren, Statistiken zu aktualisieren usw.

Ich habe keine Ahnung, warum Sybase ASE nur dann einen Index auswählt, wenn Zeichenfolgen fest codiert sind, und einen Tabellenscan auswählt, wenn aus einer anderen Tabelle ausgewählt wird.Bitte geben Sie mir einen Hinweis und danken Ihnen im Voraus.

War es hilfreich?

Lösung

1.Das Problem hier ist eine schlechte Codierung. In Ihrer Veröffentlichung sind schlechter Code und schlechtes Tischdesign die Hauptgründe (98%). Der Optimierer trifft falsche Entscheidungen (die beiden gehen Hand in Hand, ich habe den Anteil von jedem nicht herausgefunden). Beide:

    WHERE status IN ('NEW','SENT')

und

    WHERE status IN (SELECT status FROM allowableStatusValues)

sind minderwertig, da sie in beiden Fällen ASE dazu veranlassen, einen Arbeitstable für den Inhalt zwischen den Klammern zu erstellen, was leicht vermieden werden kann (und alle damit verbundenen Probleme, die damit vermieden wurden). Es besteht keine Möglichkeit von Statistiken über einen Arbeitsplatz, da die Statistiken über T.Status oder s.Status fehlen (Adamh ist korrekt an diesem Punkt), wählt sie korrekt für einen Tabellen -Scan aus.

Unterabfragen haben ihren Platz, aber niemals als Ersatz für ein reines (die Tische sind Verwandte) Join. Die Korrekturen sind:

    WHERE status = "NEW" OR status = "SENT"

und

    FROM  myTable t,
          allowableStatusValues s
    WHERE t.status = s.status

2.Die Aussage

|Jetzt müssen Sie keinen Index hinzufügen, um Statistiken in einer Spalte zu erhalten, aber Es ist wahrscheinlich der beste Weg.

ist falsch. Erstellen Sie niemals Indizes, die Sie nicht verwenden werden. Wenn Sie Statistiken in einer Spalte aktualisieren möchten, einfach

    UPDATE STATISTICS myTable (status)

3. Es ist wichtig, um sicherzustellen, dass Sie über aktuelle Statistiken zu (a) alle indizierten Spalten und (b) alle Verbindungspalten verfügen.

4.Yes, es gibt keinen Ersatz für Showplan in jedem Code -Segment, das für die Freigabe vorgesehen ist, doppelt so für jeden Code mit fragwürdiger Leistung. Du kannst auch SET NOEXEC ON, um die Ausführung zu vermeiden, z. für große Ergebnissätze.

Andere Tipps

Ein Indexhinweis wird das Problem umgehen, ist aber wahrscheinlich nicht die Lösung.

Zunächst würde ich gerne wissen, ob es einen Index für „allowableStatusValues.status“ gibt. Wenn ja, verfügt Sybase über Statistiken und hat eine gute Vorstellung von der Anzahl der darin enthaltenen Werte.Wenn nicht, hat der Optimierer wahrscheinlich keine gute Vorstellung davon, wie viele verschiedene Werte Status annehmen kann.Es muss dann davon ausgegangen werden, dass Sie fast alle Zeilen aus myTable extrahieren, und die beste Möglichkeit hierfür ist ein Tabellenscan (sofern kein abdeckender Index vorhanden ist).

Jetzt müssen Sie keinen Index hinzufügen, um Statistiken zu einer Spalte zu erhalten, aber es ist wahrscheinlich die beste Möglichkeit.

Wenn Sie einen Index für „allowableStatusValues.status“ haben, würde ich mich fragen, wie gut Ihre Statistiken sind.Besorgen Sie sich ein Exemplar von sp__optdiag.Wahrscheinlich müssen Sie auch die Werte „Histogramm-Tuning-Faktor“ und „Anzahl der Histogrammschritte“ anpassen. Wenn Sie diese gegenüber den Standardwerten leicht erhöhen, erhalten Sie detailliertere Statistiken, die dem Optimierer immer helfen.

Führen Sie immer noch einen Tischscan aus, wenn Sie die Unterabfrage durch einen Join ersetzen:

SELECT m.ID,m.status,m.dateTime 
FROM myTable m
JOIN allowableStatusValues a on m.status = a.status
ORDER BY ID 

Anstatt sich auf experimentelle Beobachtungen zu verlassen, wie lange eine Abfrage ausgeführt wird, würde ich sehr empfehlen, Sybase zu erhalten, um Ihnen die Ausführungspläne für jede Abfrage zu zeigen, zum Beispiel:

SET showplan ON
GO

-- query/procedure call goes here
SELECT id, status, datetime
FROM myTable
WHERE status IN('NEW','SENT')
ORDER BY id
GO

SET showplan OFF
GO

Mit SET showplan ON, Sybase generiert Ausführungspläne für jede Aussage, die es ausführt. Diese können von unschätzbarem Wert sein, um festzustellen, wo Abfragen nicht geeignete Indizes verwenden. Für gespeicherte Verfahren in Sybase wird der Ausführungsplan für das gesamte Verfahren generiert, wenn das gespeicherte Verfahren erstmals nach Zusammenstellung ausgeführt wird.

Wenn Sie die Pläne für jede Ihrer Anfragen posten, können wir möglicherweise mehr Licht auf das Problem werfen.

Erstaunlicherweise verwenden Sie eine Index Hinweis Löst das Problem (siehe die (Index MyIndexname) Zeile unten - neu geschriebener/vereinfachte Code unten:

-- using INDEX HINT
SELECT ID,status,dateTime 
FROM myTable (index myIndexName)
WHERE status in (select status from allowableStatusValues) 
ORDER BY ID 

Seltsam, dass ich haben Um diese Technik zu verwenden, um einen Tischscan zu vermeiden, aber es geht darum.

Garrett, indem Sie nur den vereinfachten Code anzeigen, haben Sie wahrscheinlich genau die Informationen ausgezogen, die die Quelle des Problems beleuchten würden.

Meine erste Vermutung wäre eine Art Fehlanpassung zwischen erlaubigestatusValues.status und mytable.status. Dies ist jedoch nicht die einzige Möglichkeit. Wie in Ninesided angegeben, ist die vollständige Abfragepläne (unter Verwendung von Showplan- und FMtonly -Flags) sowie die tatsächlichen Tabellendefinitionen und die Speased Procedure -Quelle mit größerer Wahrscheinlichkeit eine nützliche Antwort.

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