Sind Sie schon einmal auf eine Abfrage gestoßen, die SQL Server nicht ausführen konnte, weil sie auf zu viele Tabellen verwies?

StackOverflow https://stackoverflow.com/questions/2432

Frage

Haben Sie jemals eine dieser Fehlermeldungen gesehen?

-- SQL Server 2000

Es konnte keine Zusatztabelle für die Ansichts- oder Funktionsauflösung zugewiesen werden.
Die maximale Anzahl von Tabellen in einer Abfrage (256) wurde überschritten.

-- SQL Server 2005

Zu viele Tabellennamen in der Abfrage.Der maximal zulässige Wert beträgt 256.

Wenn ja, was haben Sie getan?

Aufgegeben?Den Kunden davon überzeugt, seine Anforderungen zu vereinfachen?Datenbank denormalisiert?


@(alle möchten, dass ich die Anfrage poste):

  1. Ich bin nicht sicher, ob ich 70 Kilobyte Code in das Antwortbearbeitungsfenster einfügen kann.
  2. Selbst wenn ich das kann, hilft das nicht, da diese 70 Kilobyte Code auf 20 oder 30 Aufrufe verweisen, die ich auch posten müsste, da der Code sonst bedeutungslos wäre.

Ich möchte hier nicht so klingen, als würde ich prahlen, aber das Problem liegt nicht in den Abfragen.Die Abfragen sind optimal (oder zumindest nahezu optimal).Ich habe unzählige Stunden damit verbracht, sie zu optimieren und nach jeder einzelnen Spalte und jeder einzelnen Tabelle zu suchen, die entfernt werden kann.Stellen Sie sich einen Bericht mit 200 oder 300 Spalten vor, der mit einer einzigen SELECT-Anweisung gefüllt werden muss (denn so wurde er vor ein paar Jahren entworfen, als es noch ein kleiner Bericht war).

War es hilfreich?

Lösung

Für SQL Server 2005 würde ich empfehlen, Tabellenvariablen zu verwenden und die Daten teilweise nach und nach zu erstellen.

Erstellen Sie dazu eine Tabellenvariable, die Ihren endgültigen Ergebnissatz darstellt, den Sie an den Benutzer senden möchten.

Suchen Sie dann Ihre primäre Tabelle (z. B. die Bestelltabelle in Ihrem Beispiel oben) und rufen Sie diese Daten sowie ein paar Zusatzdaten ab, die nur einen Join entfernt sind (Kundenname, Produktname).Sie können ein SELECT INTO ausführen, um dies direkt in Ihre Tabellenvariable einzufügen.

Von dort aus durchlaufen Sie die Tabelle und führen für jede Zeile eine Reihe kleiner SELECT-Abfragen durch, um alle zusätzlichen Daten abzurufen, die Sie für Ihre Ergebnismenge benötigen.Fügen Sie diese nach und nach in jede Spalte ein.

Sobald Sie fertig sind, können Sie ein einfaches SELECT * aus Ihrer Tabellenvariablen ausführen und diese Ergebnismenge an den Benutzer zurückgeben.

Ich habe dazu keine genauen Zahlen, aber es gab drei verschiedene Fälle, an denen ich bisher gearbeitet habe, bei denen die Durchführung dieser kleineren Abfragen tatsächlich schneller funktionierte als die Durchführung einer großen Auswahlabfrage mit einer Reihe von Verknüpfungen.

Andere Tipps

Eine solche Situation habe ich noch nie erlebt, und um ehrlich zu sein, erfüllt mich die Vorstellung, in einer Abfrage auf mehr als 256 Tabellen zu verweisen, mit Todesangst.

Ihre erste Frage sollte wahrscheinlich „Warum so viele?“ lauten, dicht gefolgt von „Welche Informationen brauche ich?“ NICHT brauchen?“ Ich befürchte, dass die von einer solchen Abfrage zurückgegebene Datenmenge auch die Leistung der Anwendung erheblich beeinträchtigen würde.

@chopeen Sie könnten die Art und Weise ändern, wie Sie diese Statistiken berechnen, und stattdessen eine separate Tabelle aller Statistiken pro Produkt führen.Wenn eine Bestellung aufgegeben wird, durchlaufen Sie die Produkte und aktualisieren die entsprechenden Datensätze in der Statistiktabelle.Dies würde einen Großteil der Berechnungslast auf die Checkout-Seite verlagern, anstatt beim Ausführen eines Berichts alles in einer großen Abfrage auszuführen.Natürlich gibt es einige Statistiken, die auf diese Weise nicht so gut funktionieren, z. B.Verfolgung der nächsten Einkäufe der Kunden nach dem Kauf eines bestimmten Produkts.

Dies passierte ständig, wenn Reporting Services-Berichte für Dynamics CRM-Installationen geschrieben wurden, die unter SQL Server 2000 ausgeführt wurden.CRM verfügt über ein gut normalisiertes Datenschema, das zu vielen Verknüpfungen führt.Es gibt tatsächlich einen Hotfix, der das Limit von 256 auf satte 260 erhöht: http://support.microsoft.com/kb/818406 (Wir hielten das immer für einen tollen Witz seitens des SQL Server-Teams).

Die Lösung besteht, wie Dillie-O andeutet, darin, geeignete „Sub-Joins“ zu identifizieren (vorzugsweise solche, die mehrfach verwendet werden) und sie in temporäre Tabellenvariablen auszugliedern, die Sie dann in Ihren Haupt-Joins verwenden.Es handelt sich um eine große PIA, die oft die Leistung beeinträchtigt.Es tut mir leid für dich.

@Kevin, ich liebe dieses T-Shirt – sagt alles :-).

Ich würde diese Abfrage gerne sehen, aber ich stelle mir vor, dass es sich um ein Problem mit einer Art Iterator handelt, und obwohl ich mir keine Situationen vorstellen kann, in denen dies möglich ist, wette ich, dass es von einem schlechten While/Fall/Cursor oder einer Menge anderer stammt schlecht umgesetzte Ansichten.

Posten Sie die Anfrage :D

Ich habe auch das Gefühl, dass eines der möglichen Probleme darin bestehen könnte, eine Menge (mehr als 200) Namens-/Werttabellen zu haben, die in einer einzigen Nachschlagetabelle zusammengefasst werden könnten.

Ich hatte das gleiche Problem...Auf meiner Entwicklungsbox läuft SQL Server 2008 (die Ansicht funktionierte einwandfrei), aber in der Produktion (mit SQL Server 2005) funktionierte die Ansicht nicht.Um diese Einschränkung zu vermeiden, habe ich schließlich Ansichten erstellt und die neuen Ansichten als Teil der Abfrage in der Ansicht verwendet, die den Fehler ausgelöst hat.

Irgendwie albern, wenn man bedenkt, dass die logische Ausführung dieselbe ist ...

Hatte das gleiche Problem in SQL Server 2005 (funktionierte 2008), als ich eine Ansicht erstellen wollte.Ich habe das Problem gelöst, indem ich eine gespeicherte Prozedur anstelle einer Ansicht erstellt habe.

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