database - Avez-vous déjà rencontré une requête que SQL Server n'a pas pu exécuter car elle faisait référence à trop de tables?

Translate

Avez-vous déjà vu l'un de ces messages d'erreur?

- SQL Server 2000

Impossible d'allouer la table auxiliaire pour la résolution de vue ou de fonction.
Le nombre maximal de tables dans une requête (256) a été dépassé.

- SQL Server 2005

Trop de noms de table dans la requête. Le maximum autorisé est de 256.

Si oui, qu'avez-vous fait?

Abandonné? Convaincu le client de simplifier ses demandes? Dénormalisé la base de données?


@ (tout le monde veut que je poste la requête):

  1. Je ne sais pas si je peux coller 70 kilo-octets de code dans la fenêtre d'édition des réponses.
  2. Même si je peux, cela n'aidera pas puisque ces 70 kilo-octets de code feront référence à 20 ou 30 vues que je devrais également publier, sinon le code n'aura aucun sens.

Je ne veux pas avoir l'air de me vanter ici, mais le problème ne réside pas dans les requêtes. Les requêtes sont optimales (ou du moins presque optimales). J'ai passé d'innombrables heures à les optimiser, à rechercher chaque colonne et chaque table pouvant être supprimées. Imaginez un rapport qui a 200 ou 300 colonnes qui doit être rempli avec une seule instruction SELECT (car c'est ainsi qu'il a été conçu il y a quelques années alors qu'il s'agissait encore d'un petit rapport).

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

Pour SQL Server 2005, je recommanderais d'utiliser des variables de table et de créer partiellement les données au fur et à mesure.

Pour ce faire, créez une variable de table qui représente votre jeu de résultats final que vous souhaitez envoyer à l'utilisateur.

Ensuite, trouvez votre table principale (disons la table des commandes dans votre exemple ci-dessus) et extrayez ces données, plus un peu de données supplémentaires, c'est-à-dire une seule jointure (nom du client, nom du produit). Vous pouvez faire un SELECT INTO pour mettre cela directement dans votre variable de table.

À partir de là, parcourez la table et pour chaque ligne, effectuez un tas de petites requêtes SELECT qui récupèrent toutes les données supplémentaires dont vous avez besoin pour votre jeu de résultats. Insérez-les dans chaque colonne au fur et à mesure.

Une fois terminé, vous pouvez alors faire un simple SELECT * à partir de votre variable de table et renvoyer ce jeu de résultats à l'utilisateur.

Je n'ai pas de chiffres précis pour cela, mais il y a eu trois cas distincts sur lesquels j'ai travaillé à ce jour où faire ces petites requêtes a en fait fonctionné plus rapidement que de faire une requête de sélection massive avec un tas de jointures.

La source
Translate

Je n'ai jamais rencontré ce genre de situation, et pour être honnête, l'idée de référencer> 256 tables dans une requête me donne une peur mortelle.

Votre première question devrait probablement être "Pourquoi tant?", Suivie de près par "Quels éléments d'information dois-jeNE PASbesoin? "Je crains que la quantité de données renvoyée par une telle requête ne commence également à avoir un impact très important sur les performances de l'application.

La source
Translate

@chopeen Vous pouvez modifier la façon dont vous calculez ces statistiques et conserver à la place un tableau séparé de toutes les statistiques par produit. Lorsqu'une commande est passée, parcourez les produits en boucle et mettez à jour les enregistrements appropriés dans le tableau des statistiques. Cela déplacerait une grande partie de la charge de calcul vers la page de paiement plutôt que de tout exécuter dans une seule énorme requête lors de l'exécution d'un rapport. Bien sûr, certaines statistiques ne fonctionneront pas aussi bien de cette façon, par exemple le suivi des prochains achats des clients après l'achat d'un produit particulier.

La source
Translate

Cela se produirait tout le temps lors de l'écriture de rapports Reporting Services pour les installations Dynamics CRM exécutées sur SQL Server 2000. CRM a un schéma de données bien normalisé qui entraîne de nombreuses jointures. Il existe en fait un correctif qui fera passer la limite de 256 à 260:http://support.microsoft.com/kb/818406(nous avons toujours pensé que c'était une bonne blague de la part de l'équipe SQL Server).

La solution, comme Dillie-O le dit, est d'identifier les «sous-jointures» appropriées (de préférence celles qui sont utilisées plusieurs fois) et de les factoriser en variables de table temporaire que vous utilisez ensuite dans vos jointures principales. C'est un PIA majeur et tue souvent les performances. Je suis désolé pour toi.

@Kevin, j'adore ce tee-shirt - dit tout :-).

La source
Translate

J'aimerais voir cette requête, mais j'imagine que c'est un problème avec une sorte d'itérateur, et bien que je ne puisse penser à aucune situation où c'est possible, je parie que c'est d'un mauvais moment / case / curseur ou une tonne de vues mal mises en œuvre.

La source
Translate

Publier la requête: D

J'ai aussi l'impression que l'un des problèmes possibles pourrait être d'avoir une tonne (lire 200+) de tables de noms / valeurs qui pourraient être condensées en une seule table de recherche.

La source
Translate

J'ai eu ce même problème ... ma boîte de développement exécute SQL Server 2008 (la vue fonctionnait bien) mais en production (avec SQL Server 2005) la vue ne fonctionnait pas. J'ai fini par créer des vues pour éviter cette limitation, en utilisant les nouvelles vues dans le cadre de la requête dans la vue qui a généré l'erreur.

Un peu idiot étant donné que l'exécution logique est la même ...

La source
Translate

J'ai eu le même problème dans SQL Server 2005 (travaillé en 2008) lorsque je voulais créer une vue. J'ai résolu le problème en créant une procédure stockée au lieu d'une vue.

La source