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.

¿Qué hace que esa consulta de PostgreSQL sea lenta?

Tengo esta consulta, donde me parece que hay demasiados JOIN.

El objetivo es recuperar todas las ubicaciones con sus detalles de envío más costosos (precio más alto) para un producto específico. Tenga en cuenta que podemos tener dos tipos diferentes de envío: Express y Standard.

SELECT DISTINCT en(l.id, sm.id) l.id como identificación de ubicación, sm.id como identificación de método de envío,
    sm.nombre como nombre del método de envío, sd.precio
DESDE la ubicación COMO l

ÚNETE A la ubicación_del_producto_del_envío COMO pl_s
    EN l.id = pl_s.location_id

ÚNETE A los detalles_de_envío_de_la_ubicación_del_producto COMO pl_sd
    EN pl_s.id = pl_sd.product_location_shipping_id

ÚNETE A los detalles_de_envío COMO sd
    EN sd.id = pl_sd.shipping_details_id

ÚNETE A la forma_de_envío COMO sm
    EN sm.id = sd.shipping_method_id
DONDE pl_s.product_id = 1
ORDENAR POR l.id, sm.id, sd.price DESC;

Y el resultado es:

identificación de ubicación identificación de método de envío nombre del método de envío precio
1 1 Estándar 230
1 2 Express 500
6 1 Estándar 3900
6 2 Express 5230

Aquí está la estructura de las tablas. (Cada columna representa una tabla)

ubicación método de envío detalles de envío envío de ubicación del producto detalles de envío de la ubicación del producto
id id id id id
nombre nombre precio identificación de ubicación identificación de envío de ubicación del producto
código postal tiempo estimado identificación de producto identificación de detalles de envío
.. identificación del método de envío

¿Hay alguna otra forma de lograr esto más rápido? o tal vez estoy haciendo algo mal.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Hay algunas cosas que podrían mejorar potencialmente el rendimiento de la consulta:

    1. En lugar de usar DISTINCT ON, que puede ser lento en conjuntos de datos grandes, considere usar una subconsulta para seleccionar el precio máximo para cada combinación de ubicación y método de envío:
    SELECT l.id AS location_id, sm.id AS shipping_method_id, sm.name AS shipping_method_name, sd.price
    FROM location AS l
    JOIN product_location_shipping AS pl_s ON l.id = pl_s.location_id 
    JOIN product_location_shipping_details AS pl_sd ON pl_s.id = pl_sd.product_location_shipping_id
    JOIN shipping_details AS sd ON sd.id = pl_sd.shipping_details_id
    JOIN shipping_method AS sm ON sm.id = sd.shipping_method_id
    WHERE pl_s.product_id = 1
    AND (l.id, sm.id, sd.price) IN (
      SELECT l2.id, sm2.id, MAX(sd2.price)
      FROM location AS l2
      JOIN product_location_shipping AS pl_s2 ON l2.id = pl_s2.location_id 
      JOIN product_location_shipping_details AS pl_sd2 ON pl_s2.id = pl_sd2.product_location_shipping_id
      JOIN shipping_details AS sd2 ON sd2.id = pl_sd2.shipping_details_id
      JOIN shipping_method AS sm2 ON sm2.id = sd2.shipping_method_id
      WHERE pl_s2.product_id = 1
      GROUP BY l2.id, sm2.id
    )
    ORDER BY l.id, sm.id, sd.price DESC;
    
    1. Verifique si todas las columnas utilizadas en las condiciones de unión y la cláusula WHERE tienen índices. En particular, product_id en la tabla product_location_shipping y shipping_details_id en la tabla product_location_shipping_details deben tener índices.

    2. Considere la desnormalización de los datos agregando el precio máximo para cada combinación de ubicación y método de envío como una columna en la tabla location. Esto haría que la consulta fuera más rápida, pero también aumentaría la redundancia de datos y agregaría cierta complejidad al mantenimiento de datos. Esta opción debe evaluarse cuidadosamente según el caso de uso específico.

Comments are closed.