110 votes

Contourner l'erreur "Can't reopen table" de MySQL

Je suis actuellement occupé à mettre en œuvre une sorte de filtre pour lequel je dois générer une clause INNER JOIN pour chaque "tag" à filtrer.

Le problème est qu'après tout un tas de SQL, j'ai une table qui contient toutes les informations dont j'ai besoin pour faire ma sélection, mais j'en ai à nouveau besoin pour chaque INNER JOIN généré.

En gros, ça ressemble à ça :

SELECT
    *
FROM search
INNER JOIN search f1 ON f1.baseID = search.baseID AND f1.condition = condition1
INNER JOIN search f2 ON f2.baseID = search.baseID AND f2.condition = condition2
...
INNER JOIN search fN ON fN.baseID = search.baseID AND fN.condition = conditionN

Cela fonctionne mais je préférerais de loin que la table de "recherche" soit temporaire (elle peut être plus petite de plusieurs ordres de grandeur si elle n'est pas une table normale) mais cela me donne une erreur très ennuyeuse : Can't reopen table

Quelques recherches m'amènent à ce rapport de bogue mais les gens de MySQL ne semblent pas se soucier du fait qu'une fonctionnalité aussi basique (utiliser une table plus d'une fois) ne fonctionne pas avec les tables temporaires. Je rencontre de nombreux problèmes d'évolutivité avec cette question.

Existe-t-il une solution de rechange viable qui ne m'oblige pas à gérer des tas de tables temporaires mais bien réelles ou à maintenir une énorme table avec toutes les données qu'elle contient ?

Cordialement, Kris

[supplémentaire]

La réponse GROUP_CONCAT ne fonctionne pas dans mon cas, car mes conditions sont des colonnes multiples dans un ordre spécifique, ce qui ferait des OU à partir de ce dont j'ai besoin pour être des ET. Cependant, elle m'a aidé à résoudre un problème antérieur, de sorte que la table, temporaire ou non, n'est plus nécessaire. Nous avions simplement une vision trop générique pour notre problème. L'ensemble de l'application des filtres a maintenant été ramené d'environ une minute à bien moins d'un quart de seconde.

7 votes

J'ai eu le même problème en utilisant une table temporaire deux fois dans la même requête en utilisant UNION.

0 votes

Je vais juste utiliser une vraie table alors.

1voto

Inc33 Points 625

Vous pouvez contourner ce problème en créant une table permanente, que vous supprimerez par la suite, ou en créant deux tables temporaires distinctes contenant les mêmes données.

1voto

Tanner Clark Points 453

enter image description here

Voici la documentation de MYSQL sur ce problème. J'utilise des tables temporaires dupliquées comme certaines des réponses ci-dessus, cependant, vous pouvez avoir une situation où un CTE est approprié !

https://dev.mysql.com/doc/refman/8.0/en/temporary-table-problems.html

0voto

le dorfier Points 27267

A quel point est-ce énorme ? D'où viennent les données à mettre dans la table temporaire ? S'agit-il d'un ensemble de tables semi-immenses ? Ou un grand nombre de petites tables sans rapport les unes avec les autres qui nécessitent un grand nombre d'opérations de plomberie pour obtenir votre table temporaire ? Quelle serait la différence entre la table énorme et la table temporaire ?

Est-ce quelque chose qui pourrait être invoqué par plusieurs personnes simultanément, de sorte qu'une vraie table provoquerait des collisions ?

J'ai généralement constaté que MySQL est plus heureux si vous vous en tenez à ses objets courants, et vous faites déjà quelque chose d'assez délicat avec toutes les auto-jointes. À moins que "énorme" ne signifie plusieurs gigaoctets, je vous suggère d'essayer de faire des requêtes à partir des sources primaires. Ou alors, créez une table permanente et utilisez-la temporairement.

Dans "fN", N = ?

0voto

J'ai pu changer la requête en une table permanente et cela a réglé le problème pour moi. ( j'ai changé les paramètres VLDB dans MicroStrategy, type de table temporaire).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X