es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Unir múltiples tablas a la izquierda en SQL como nuevas columnas para obtener un mejor rendimiento.

Tengo 3 tablas:

cuenta

id nombre
1 Google
2 Apple

campo_personalizado

id nombre
1 Teléfono
2 Correo electrónico

envío_campo_personalizado

id id_campo_personalizado id_entidad valor
1 1 1 555-444-333
2 1 2 111-111-111
3 2 1 google@goog.com
4 2 2 apple@apple.com

Resultado esperado después de la consulta

id nombre Teléfono Correo electrónico
1 Google 555-444-333 google@goog.com
2 Apple 111-111-111 apple@apple.com

Tengo una consulta como esta:

lang-sql
SELECT
a.id,
a.nombre,
telefono.valor as telefono,
correo.valor as correo

FROM cuenta a

LEFT JOIN (
SELECT DISTINCT envío_campo_personalizado.valor, envío_campo_personalizado.id_entidad
FROM envío_campo_personalizado
WHERE envío_campo_personalizado.id_campo_personalizado = 1) AS telefono
ON telefono.id_entidad = a.id

LEFT JOIN (
SELECT DISTINCT envío_campo_personalizado.valor, envío_campo_personalizado.id_entidad
FROM envío_campo_personalizado
WHERE envío_campo_personalizado.id_campo_personalizado = 2) AS correo
ON correo.id_entidad = a.id

En realidad tengo 20 campos personalizados para 10,000 cuentas. Cuando ejecuto la consulta, es muy lenta (3-4 segundos).

¿Tienes alguna idea para optimizar esto?

Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, una idea para optimizar esta consulta es utilizar una tabla dinámica en lugar de múltiples uniones izquierdas. Podemos utilizar consultas de pivote dinámicas para generar columnas para cada campo personalizado. Aquí hay un ejemplo de consulta:

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'MAX(CASE WHEN custom_field_submission.custom_field_id = ''',
          custom_field.id,
          ''' THEN custom_field_submission.value END) AS `',
          custom_field.name, '`'
        )
      ) INTO @sql
    FROM
      custom_field;
    
    SET @sql = CONCAT('SELECT account.id, account.name, ', @sql, ' 
                      FROM account
                      LEFT JOIN custom_field_submission
                        ON account.id = custom_field_submission.entity_id
                      LEFT JOIN custom_field
                        ON custom_field_submission.custom_field_id = custom_field.id
                      GROUP BY account.id, account.name');
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    

    Esta consulta generará columnas para cada campo personalizado y utilizará MAX para obtener el valor para cada par cuenta-entidad. Luego agrupará por el ID y el nombre de la cuenta para obtener una sola fila para cada cuenta. Esto hará que la consulta sea más rápida y escalable, ya que solo se realizará una unión en la tabla dinámica en lugar de unirse a cada campo personalizado por separado.

Comments are closed.