5

¿Cuál es una buena manera de trabajar con muchas filas en MySql, dado que tengo una larga lista de claves en una aplicación cliente que se conecta con ODBC?MySql: Operar en muchas filas usando la lista larga de PK compuestas

Nota: mi experiencia es en gran medida SQL Server, así que sé un poco, simplemente no MySQL específicamente.

La tarea consiste en eliminar algunas filas de 9 tablas, pero podría tener más de 5.000 pares de claves.

Empecé con el camino más fácil de bucle a través de todas las llaves y la presentación de una declaración para cada uno contra cada mesa, tales como:

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 
... 

Excepto, que sale a 45.000 declaraciones separadas, que como te puedes imaginar es un poco lento.

Así que, sin preocuparme por el lenguaje de programación que estoy usando en el front-end, ¿cuál es una buena forma de enviar la lista para poder UNIRME y hacer la operación todo al mismo tiempo o al menos en lotes grandes? Aquí están mis ideas hasta el momento:

  • Crear una tabla temp e insertar a ella, y luego unirse. Con mucho gusto buscaré la sintaxis de MySQL para crear una tabla temporal, pero ¿es una buena ruta para seguir?

  • Suponiendo que utilizo una tabla temporal, ¿cuál es el mejor método para rellenar una tabla temporal? 5000 INSERT Table VALUES() declaraciones? SELECT 123, 456 UNION ALL SELECT 124, 457? Acabo de probar que MySql permite este tipo de SELECT que no se publica en una tabla. Pero SQL Server eventualmente explota si la lista es demasiado larga, ¿es esta una buena forma en MySQL? ¿Debo mantener la lista a unos pocos cientos a la vez?

    --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. Veo que MySQL 5.1 tiene algunas funciones XML, pero a partir de una búsqueda superficial, no parece ser compatible con convertir un trozo de texto XML en un conjunto de filas para unir. ¿Es eso cierto? Es extremadamente fácil para mí obtener los valores en XML.

  • Operación dividida virtual. Presumo en MySql que existe algún tipo de lenguaje de procedimiento posible. En SQL Server que podría escribir algo de código personalizado que analiza una cadena y lo convierte en un conjunto de filas:

    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 
    

Desde que estoy familiarizado con MySQL, realmente no saben cuales posibilidad de investigar en primer lugar, y agradecería algo de ayuda para salvarme de tomar una mala decisión y/o aprender por las malas.

Respuesta

2

Usaría la solución de tabla temporal y la uniría a cada tabla principal en las instrucciones DELETE. Entonces solo tiene que hacer nueve eliminaciones, una para cada tabla.

  • CREATE TEMPORARY TABLE

    CREATE TEMPORARY TABLE Keys (
        Key1 INT UNSIGNED NOT NULL, 
        Key2 INT UNSIGNED NOT NULL, 
        PRIMARY KEY(Key1, Key2) 
    ); 
    
  • carga un archivo de datos separados por tabuladores en la tabla temporal utilizando LOAD DATA LOCAL INFILE

    LOAD DATA LOCAL INFILE 'C:/path/to/datafile' INTO TABLE Keys; 
    
  • eliminar utilizando la sintaxis de varias mesas 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 tu comentario:

Los documentos MySQL en CREATE TABLE decir lo siguiente:

una tabla temporal es visible sólo para la conexión actual, y se deja caer automáticamente cuando la conexión está cerrada. Esto significa que dos conexiones diferentes pueden usar el mismo nombre de tabla temporal sin entrar en conflicto entre sí o con una tabla existente no TEMPORAL del mismo nombre. (La tabla existente está oculta hasta que se abandona la tabla temporal.)

¡Está bastante claro!

En cuanto a la carga de datos, puede hacerlo con INSERT. 5000 filas no es gran cosa. Utilizo un script PHP para cargar millones de filas (por ejemplo, el volcado de datos XML de StackOverflow) en MySQL y eso solo demora unos 20 minutos. Uso una declaración preparada y luego la ejecuto con parámetros.

+0

Gracias Bill, parece dinamita. Analizaré el método LOAD DATA, aunque no estoy seguro de poder escribir fácilmente en dicho archivo. ¿Hay alguna otra forma de script para cargar la tabla temporal? Además, ¿podría elaborar un poco sobre el alcance de las tablas temporales (qué ocurre si dos sesiones intentan crear una tabla temporal con el mismo nombre, o el nombre ya existe como una tabla real, y la tabla temporal se destruye cuando la conexión cierra)? – ErikE

+0

P.S. USAR es genial, desearía que SQL Server lo tuviera. – ErikE

+0

Ojalá pudiera darle más de un voto positivo. Gracias por la profundidad y el detalle de tu respuesta. Admito que podría haber investigado todas estas cosas (y planeo hacerlo todavía), pero una buena respuesta es tan buena. – ErikE

Cuestiones relacionadas