5

Quelle est une bonne façon de travailler avec beaucoup de lignes dans MySQL, étant donné que j'ai une longue liste de clés dans une application client qui se connecte avec ODBC?MySql: fonctionne sur beaucoup de lignes en utilisant une longue liste de PK composites

Remarque: mon expérience est en grande partie SQL Server, donc je sais un peu, mais pas spécifiquement MySQL.

La tâche consiste à supprimer certaines lignes de 9 tables, mais je pourrais avoir plus de 5 000 paires de clés.

J'ai commencé avec la manière facile de boucle à travers toutes mes clés et de soumettre une déclaration pour chacun contre chaque table, tels que:

DELETE FROM Table WHERE Key1 = 123 AND Key2 = 567 -- and 8 more tables 
DELETE FROM Table WHERE Key1 = 124 AND Key2 = 568 -- and 8 more tables 
DELETE FROM Table WHERE Key1 = 125 AND Key2 = 569 -- and 8 more tables 
... 

Sauf, qui sort à 45.000 déclarations distinctes, comme vous pouvez imaginer est un peu lent. Donc, sans m'inquiéter du langage de programmation que j'utilise sur le frontal, quelle est la bonne façon de soumettre la liste pour que je puisse JOINDRE et faire l'opération tout d'un coup ou au moins en gros lots? Voici mes idées à ce jour:

  • Créer une table temporaire et insérez à, puis rejoindre. Je chercherai volontiers la syntaxe de MySQL pour créer une table temporaire, mais est-ce une bonne voie à suivre?

  • En supposant que j'utilise une table temporaire, quelle est la meilleure méthode pour remplir une table temporaire? 5000 INSERT Table VALUES() déclarations? SELECT 123, 456 UNION ALL SELECT 124, 457? Je viens de tester que MySql permet ce type de SELECT qui n'est pas émis contre une table. Mais SQL Server finit par exploser si la liste devient trop longue, alors est-ce un bon moyen dans MySQL? Devrais-je garder la liste à quelques centaines à la fois?

    --CREATE Temp Table (I do not know the syntax in MySql yet) 
    
    INSERT INTO TempTable 
    SELECT 123, 456 
    UNION ALL SELECT 124, 457 
    UNION ALL SELECT 125, 458 
    
    DELETE T 
    FROM 
        Table T 
        INNER JOIN TempTable X ON T.Key1 = X.Key1 AND T.Key2 = X.Key2 
    
  • XML. Je vois que MySQL 5.1 a des fonctions XML, mais à partir d'une recherche rapide, il ne semble pas possible de transformer un morceau de texte XML en un ensemble de lignes à rejeter. Est-ce vrai? Il m'est extrêmement facile d'obtenir les valeurs en XML.

  • Une opération de division virtuelle . Je suppose dans MySQL qu'il y a un langage procédural possible. Dans SQL Server je pourrais écrire un code personnalisé contenant une chaîne et il se transforme en un ensemble de lignes:

    CREATE PROCEDURE DoStuff @KeyString varchar(max) 
    AS 
    DECLARE @Keys TABLE (
        Key1 int, 
        Key2 int, 
        PRIMARY KEY CLUSTERED (Key1, Key2) 
    ) 
    DECLARE @Pos int 
    WHILE @Pos < Len(@KeyString) BEGIN 
        -- loop to search for delimiting commas in @KeyString 
        -- and insert pairs of parsed tokens to table variable @Keys 
    END 
    
    DELETE T 
    FROM 
        Table T 
        INNER JOIN @Keys K ON T.Key1 = K.Key1 AND T.Key2 = K.Key2 
    

Depuis que je suis peu familier avec MySQL, je ne sais vraiment pas quelle possibilité d'enquêter d'abord, et j'apprécierais de l'aide pour m'éviter de prendre une mauvaise décision et/ou d'apprendre à la dure.

Répondre

2

J'utiliserais la solution de table temporaire et la joindrais à chaque table principale dans les instructions DELETE. Il suffit donc de faire neuf suppressions, une pour chaque table.

  • CREATE TEMPORARY TABLE

    CREATE TEMPORARY TABLE Keys (
        Key1 INT UNSIGNED NOT NULL, 
        Key2 INT UNSIGNED NOT NULL, 
        PRIMARY KEY(Key1, Key2) 
    ); 
    
  • Charge un fichier de données séparées par des tabulations dans la table temporaire à l'aide LOAD DATA LOCAL INFILE

    LOAD DATA LOCAL INFILE 'C:/path/to/datafile' INTO TABLE Keys; 
    
  • supprimer à l'aide multi-table syntaxe DELETE de MySQL.

    DELETE t FROM Table1 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table2 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table3 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table4 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table5 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table6 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table7 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table8 t JOIN Keys USING (Key1, Key2); 
    DELETE t FROM Table9 t JOIN Keys USING (Key1, Key2); 
    

Re votre commentaire:

Les docs MySQL sur CREATE TABLE disent les suivantes:

Une table temporaire est visible uniquement à la connexion en cours, et il est tombé automatiquement lorsque la connexion est fermée. Cela signifie que deux connexions différentes peuvent utiliser le même nom de table temporaire sans conflit entre elles ou avec une table non-TEMPORARY existante du même nom. (La table existante est masquée jusqu'à ce que la table temporaire soit supprimée.)

C'est assez clair! En ce qui concerne le chargement des données, vous pouvez simplement le faire avec INSERT En ce qui concerne le chargement des données, vous pouvez le faire avec INSERT. 5000 lignes n'est pas une grosse affaire. J'utilise un script PHP pour charger millions de lignes (par exemple le vidage de données XML StackOverflow) dans MySQL et cela ne prend que 20 minutes. J'utilise une instruction préparée, puis l'exécute avec des paramètres.

+0

Merci Bill, ça ressemble à de la dynamite. Je me pencherai sur la méthode LOAD DATA, même si je ne suis pas sûr que je serai capable d'écrire facilement dans un tel fichier. Existe-t-il un autre moyen de script pour charger la table temporaire? Aussi, pourriez-vous élaborer un peu sur la portée des tables temporaires (que se passe-t-il si deux sessions tentent de créer une table temporaire avec le même nom ou si le nom existe déjà en tant que table réelle? se ferme)? – ErikE

+0

P.S. L'UTILISATION est cool, je souhaite que SQL Server ait cela. – ErikE

+0

Je voudrais pouvoir vous donner plus d'un upvote. Merci pour la profondeur et le détail de votre réponse. J'avoue que j'aurais pu aller faire des recherches sur toutes ces choses (et je prévois de le faire encore), mais une belle réponse ronde est vraiment géniale. – ErikE

Questions connexes