La consulta a continuación se está volviendo más lenta ya que he usado la declaración de caso en la cláusula de tener y los datos son muy grandes, por lo que la consulta a continuación está tomando tiempo para obtener los datos tan grandes para superar esto. Necesito una solución alternativa en lugar de la cláusula de tener con declaración de caso .
Explicación sobre la consulta,
Necesito obtener los datos por algunos tipos con condiciones como tengo tres tipos Monto fijo (1), monto fijo de alquiler (2) y porcentaje de alquiler (3) sobre esa base, necesito hacer la SUMA de los cargos con condiciones como si el tipo es 2, luego obtenga el registro con el tipo de cargo es 2 y el código de cargo es 3 así. Mire la consulta a continuación y sugiera que existe una solución alternativa,
SELECT n.id, ro.id, n.notice_amount, n.notice_type_id, SUM ( c.charge_amount ) AS charge_amount FROM notification n JOIN notification_doc_groups ndg ON ( ndg.notice_id = n.id AND ndg.is_published = TRUE ) JOIN properties p ON ( p.id = ndg.property_id ) JOIN customer_details cd ON ( cd.notification_id = n.id ) JOIN rent_out ro ON ( ro.property_id = p.id ) JOIN charges c ON ( c.rent_out_id = ro.id ) WHERE ( ( n.notice_type_id = 1 AND c.charge_amount > 0 AND c.charge_type_id = 2 ) OR ( n.notice_type_id = 2 AND c.charge_type_id = 2 AND c.charge_code = 3 ) OR ( n.notice_type_id = 3 AND c.scheduled_id IS NOT NULL ) ) GROUP BY n.id, ro.id, n.notice_type_id, n.notice_amount HAVING CASE WHEN n.notice_type_id = 1 THEN ( ( sum ( c.charge_amount ) >= n.notice_amount ) ) WHEN n.notice_type_id = 2 THEN sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 ) -- or( ) WHEN n.notice_type_id = 3 THEN sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 ) END;Gracias
Puedes probar esto:
HAVING (n.notice_type_id = 1 AND sum ( c.charge_amount ) >= n.notice_amount) OR ( n.notice_type_id IN (2,3) AND n.notice_amount / 100 >=1)Supongo que el planificador no puede optimizar para el caso, así que pruebe con una matriz:
having (array[ sum ( c.charge_amount ) >= n.notice_amount, sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 ), sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 ) ]::bool[])[n.notice_type_id]Puede separar los tres casos diferentes y usar una unión para unirlos. No debería marcar una diferencia en los resultados, pero podría facilitar las cosas para el optimizador. Por lo menos, podrá ejecutar cada tipo de aviso por separado y ver si alguno está causando la ralentización.
Sin embargo, estoy un poco confundido acerca de la condición en los tipos de aviso 2 y 3:
sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 )Parece que no necesita verificar el monto del cargo en absoluto, solo puede encontrar entradas donde el monto del aviso sea 100 o menos.
SELECT n.id, ro.id, n.notice_amount, n.notice_type_id, SUM ( c.charge_amount ) AS charge_amount FROM notification n JOIN notification_doc_groups ndg ON ( ndg.notice_id = n.id AND ndg.is_published = TRUE ) JOIN properties p ON ( p.id = ndg.property_id ) JOIN rent_out ro ON ( ro.property_id = p.id ) JOIN charges c ON ( c.rent_out_id = ro.id ) WHERE n.notice_type_id = 3 AND c.scheduled_id IS NOT NULL GROUP BY n.id, ro.id, n.notice_type_id, n.notice_amount HAVING sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 ) UNION ALL SELECT n.id, ro.id, n.notice_amount, n.notice_type_id, SUM ( c.charge_amount ) AS charge_amount FROM notification n JOIN notification_doc_groups ndg ON ( ndg.notice_id = n.id AND ndg.is_published = TRUE ) JOIN properties p ON ( p.id = ndg.property_id ) JOIN rent_out ro ON ( ro.property_id = p.id ) JOIN charges c ON ( c.rent_out_id = ro.id ) WHERE n.notice_type_id = 2 AND c.charge_type_id = 2 GROUP BY n.id, ro.id, n.notice_type_id, n.notice_amount HAVING sum ( c.charge_amount ) >= sum ( c.charge_amount ) * ( n.notice_amount / 100 ) UNION ALL SELECT n.id, ro.id, n.notice_amount, n.notice_type_id, SUM ( c.charge_amount ) AS charge_amount FROM notification n JOIN notification_doc_groups ndg ON ( ndg.notice_id = n.id AND ndg.is_published = TRUE ) JOIN properties p ON ( p.id = ndg.property_id ) JOIN rent_out ro ON ( ro.property_id = p.id ) JOIN charges c ON ( c.rent_out_id = ro.id ) WHERE n.notice_type_id = 1 AND c.charge_amount > 0 AND c.charge_type_id = 2 GROUP BY n.id, ro.id, n.notice_type_id, n.notice_amount HAVING sum ( c.charge_amount ) >= n.notice_amount