How to decrease Query Time - Postgresql - postgresql

PostgreSQL 9.6.9, compiled by Visual C++ build 1800, 64-bit
I have a question about query time. This 'view' has +1M data and when you execute select*from view , its query time is +400 seconds. On my query, it returns 10k data and query time is around 8-10 seconds. I am looking for a way to decrease it to 1 or 2 seconds. I tried changing or deleting things in my where or select clause, but only solution i came up with is limiting between "time" part.
If anyone know a better solution, that would be appreciated!
Thanks,
Can
Note: This view contains three different tables(cl_segments,cl_participants,cl_party_info).
I could not find a definition for those tables but i will add pictures of indexes and fields. Please let me know if you need any additional information.
clparticipantfields
clparticipantindexes
clpartyinfofields
clpartyinfoindexes
clsegmentsfields
clsegmentsindexes
EXPLAIN ANALYZE BUFFERS
select distinct on (clsgview.call_id)clsgview.call_id as call_id,
case when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = '0' then
right(clsgview.src_dn,11)
when clsgview.src_dn_type = '1' and clsgview.dst_dn_type = '0' then
right(clsgview.src_caller_number,11)
when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = ANY (ARRAY[1,12,13]) then
right(clsgview.src_dn,11) end as from,
case when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = '0' then
right(clsgview.dst_dn,11)
when clsgview.src_dn_type = '1' and clsgview.dst_dn_type = '0' then
right(clsgview.dst_dn,11)
when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = ANY (ARRAY[1,12,13]) then
right(clsgview.dst_display_name,11) end as to,
case when clsgview.act = ANY (ARRAY[5,6]) and clsgview.dst_dn_type != ANY (ARRAY[12]) then (end_time-start_time) else '00:00:00' end as talktime
from
( SELECT s.call_id,
s.id AS seg_id,
s.type AS seg_type,
s.seq_order AS seg_order,
s.start_time,
s.end_time,
si.dn_type AS src_dn_type,
si.dn AS src_dn,
si.display_name AS src_display_name,
si.firstlastname AS src_firstlastname,
si.caller_number AS src_caller_number,
dp.start_time AS dst_start_time,
dp.answer_time AS dst_answer_time,
dp.end_time AS dst_end_time,
dp.billing_rate AS dst_billing_rate,
di.dn_type AS dst_dn_type,
di.dn AS dst_dn,
di.display_name AS dst_display_name,
di.firstlastname AS dst_firstlastname,
di.caller_number AS dst_caller_number,
di.dn_class AS dst_dn_class,
s.action_id AS act,
ai.dn_type AS act_dn_type,
ai.dn AS act_dn,
ai.display_name AS act_display_name,
ai.firstlastname AS act_firstlastname
FROM ((((((cl_segments s
JOIN cl_participants sp ON ((sp.id = s.src_part_id)))
JOIN cl_participants dp ON ((dp.id = s.dst_part_id)))
JOIN cl_party_info si ON ((si.id = sp.info_id)))
JOIN cl_party_info di ON ((di.id = dp.info_id)))
LEFT JOIN cl_participants ap ON ((ap.id = s.action_party_id)))
LEFT JOIN cl_party_info ai ON ((ai.id = ap.info_id)))
order by seg_id desc
) as clsgview
where clsgview.src_dn_type = ANY (ARRAY[0,1])
and clsgview.dst_dn_type = ANY (ARRAY[0,1,12,13])
and clsgview.act != ANY (ARRAY[1]) and ((clsgview.act = ANY (ARRAY[15,101,102,103,107,400,409,418,419,421,423])) or (clsgview.act = ANY (ARRAY[5,6]) and clsgview.dst_dn_type = ANY (ARRAY[12])))
and clsgview.dst_display_name not like '*%' and clsgview.dst_caller_number not like '*%'
and (clsgview.src_dn = '1004' or clsgview.dst_dn = '1004')
and start_time::date BETWEEN '2020-01-01'::DATE and now()::DATE
order by clsgview.call_id desc

Related

The multi-part identifier could not be bound - SQL Server 2016

SELECT clm.CLCL_PAYEE_PR_ID, clm.SBSB_CK, clm.CLCL_ID, clm.clcl_id_adj_to,clm.clcl_id_adj_from, clm.CLCL_PAID_DT
FROM ODW.DW.fac_cmc_clcl_claim CLM
INNER JOIN ODW.DW.fac_cmc_meme_member MEME ON MEME.meme_ck = CLM.meme_ck
INNER JOIN ODW.DW.fac_cmc_mepe_prcs_elig MEPE ON MEPE.meme_ck = MEME.meme_ck
INNER JOIN ODW.DW.fac_cmc_mepr_prim_prov MEPR ON MEPE.meme_ck = MEPR.meme_ck AND CLM.clcl_prpr_id_pcp = MEPR.prpr_id
INNER JOIN ODW.DW.fac_cmc_sbsb_subsc SBSB ON MEME.sbsb_ck = SBSB.sbsb_ck
INNER JOIN ODW.DW.fac_cmc_prpr_prov PROV ON MEPR.prpr_id = PROV.prpr_id AND PROV.prpr_mctr_prty = 'RISK'
INNER JOIN ODW.DW.fac_cmc_prer_relation PRER ON PRER.prpr_id = MEPR.prpr_id
INNER JOIN ODW.DW.fac_cmc_plds_plan_desc PLDS ON MEPE.cspi_id = PLDS.cspi_id
INNER JOIN ODW.DW.fac_cmc_pdds_prod_desc PDDS ON MEPE.pdpd_id = PDDS.pdpd_id
WHERE CLM.clcl_paid_dt BETWEEN '2019-12-24 00:00:00.000' AND '2019-12-30 23:59:59.997'
AND CLM.clcl_cur_sts = '02'
AND CLM.clcl_cl_type = 'M'
AND CLM.clcl_cl_sub_type = 'H'
AND CLM.grgr_ck IN (46)
AND MEPR.grgr_ck IN (46)
AND MEPE.grgr_ck IN (46)
AND MEPE.mepe_elig_ind = 'Y'
AND CLM.clcl_low_svc_dt BETWEEN MEPE.mepe_eff_dt AND MEPE.mepe_term_dt
AND CLM.clcl_low_svc_dt BETWEEN MEPR.mepr_eff_dt AND MEPR.mepr_term_dt
AND SBSB.grgr_ck IN (46)
AND PRER.prer_prpr_entity = 'I'
AND PRER.prer_prpr_id IN ('64456546')
AND (PLDS.plds_desc LIKE '%risk%' OR PDDS.pdds_desc LIKE '%risk%');
This query runs in PROD with different variables which substitute the value of the hard coded values. It runs around 100 times per day in PROD and on some days some of the runs fail due to this error:
The multi-part identifier "PDDS.pdds_desc" could not be bound
Please note that all the joins are being done on views.
When I re-run the failed process, it succeeds the second time with no changes to the underlying query.
Can anyone suggest what could be the issue. Also, any performance optimization suggestions for this query query will be appreciated.
Thanks!

How to have CASE statement look at previous records in the statement

I have the following code generating a case statement in which I would like all future time periods to return 'Graduated' if the student graduated in a previous time period. Here is the current code:
SELECT DISTINCT
Z1.StudentID,
Z1.AcadLevel,
Z1.StudentAcadLevel,
Z1.StudentCohortStartDate,
Z1.PeriodID,
Z2.CourseTimePeriod,
Z3.DegreeTimePeriod,
CASE
WHEN Z1.PeriodID = '0' THEN 'CohortStart'
WHEN Z3.DegreeTimePeriod <= Z1.PeriodID THEN 'Graduated'
WHEN Z1.PeriodID = Z2.CourseTimePeriod THEN 'Retained'
WHEN Z2.CourseTimePeriod IS NULL THEN 'Churned'
ELSE 'Fix Me'
END AS TimePeriodStatus
FROM Z_Retention_StudentTimePeriodStatus Z1
LEFT OUTER JOIN Z_Retention_StudentCourseRegistrations Z2 ON Z2.StudentID = Z1.StudentID AND Z2.STC_ACAD_LEVEL = Z1.AcadLevel AND Z2.CourseTimePeriod = Z1.PeriodID
LEFT OUTER JOIN Z_Retention_StudentDegree Z3 ON Z3.StudentID = Z1.StudentID AND Z3.DegreeAcadLevel = Z1.AcadLevel AND Z3.DegreeTimePeriod = Z1.PeriodID
ORDER BY Z1.StudentID, Z1.PeriodID, Z2.CourseTimePeriod
In the attached image, I'm hoping to add a line to the case statement that would make the highlighted rows return 'Graduated' rather than 'Churned'.

Case When isnt returning data for the null

I have a case statement that is not returning a null value. What am I missing in to get this to work.
Select CASE
WHEN transfer_sources.input_lot_type = 'Dried' THEN Sum(transfer_sources.weight)
WHEN transfer_sources.input_lot_type = 'Fresh' THEN NULL
END
from transfer_sources join bulk_lots on transfer_sources.source_id = bulk_lots.id
where transfer_sources.input_lot_type = 'Dried' and bulk_lots.name = 'BS190208-010'
group by transfer_sources.input_lot_type
LIMIT 1
I would like a null to show in the fresh column as i am trying to only calculate for dried
You need to remove WHERE condition transfer_sources.input_lot_type = 'Dried':
Select CASE
WHEN transfer_sources.input_lot_type = 'Dried' THEN Sum(transfer_sources.weight)
WHEN transfer_sources.input_lot_type = 'Fresh' THEN NULL
END
from transfer_sources join bulk_lots on transfer_sources.source_id = bulk_lots.id
where bulk_lots.name = 'BS190208-010'
group by transfer_sources.input_lot_type

How to select from subquery if column contains a specific value in postgre

I would like to ask if it is possible to select again from a result set if a column contains a specific value?
For example, from the below query I want to select it as subquery and check if that subquery's first column contains both 2 and 3 result. Otherwise, no values should be return.
select e.evaluator_id, ROUND(avg(cast(e.rating_score as int))::numeric,1)::varchar, c.q_category_name
from tms.t_evaluation e
inner join tms.m_q_category c
on e.nendo=c.nendo
and e.q_category_id = c.q_category_id
and c.delete_flg = '0'
inner join tms.m_q_subcategory qs
on e.q_category_id = qs.q_category_id
and e.q_subcategory_id = qs.q_subcategory_id
and c.nendo = qs.nendo
and qs.delete_flg = '0'
where e.nendo = '2018'
and e.empl_id = 'empl05'
and e.delete_flg = '0'
and e.evaluator_id in ('2' , '3')
group by e.empl_id, e.nendo, e.q_category_id,
c.q_category_name, e.evaluator_id, e.history_no
Result contains both 2 and 3 in first column. Is this possible?
select e.evaluator_id, ROUND(avg(cast(e.rating_score as int))::numeric,1)::varchar, c.q_category_name
from tms.t_evaluation e
inner join tms.m_q_category c
on e.nendo=c.nendo
and e.q_category_id = c.q_category_id
and c.delete_flg = '0'
inner join tms.m_q_subcategory qs
on e.q_category_id = qs.q_category_id
and e.q_subcategory_id = qs.q_subcategory_id
and c.nendo = qs.nendo
and qs.delete_flg = '0'
where e.nendo = '2018'
and e.empl_id = 'empl05'
and e.delete_flg = '0'
and e.evaluator_id in (select case when evaluator_id=2 or evaluator_id=3 then evaluator_id else null from t_evaluation order by evaluator_id asc)
group by e.empl_id, e.nendo, e.q_category_id,
c.q_category_name, e.evaluator_id, e.history_no

Variable "Rs.Temp" not found

I'm getting error while executing a sql query in Alpha Anywhere Query (AlphaADO) section.
The code i'm executing is attached.
SELECT * FROM
(SELECT
tbl_wo_kitting.wo_kitting_id,
tbl_wo_kitting.level_no,
tbl_wo_kitting.line_no_parent,
tbl_wo_kitting.line_no AS kitting_line_no,
tbl_wo_kitting.production_type,
tbl_wo_kitting.quantity AS kitting_quantity,
tbl_wo_kitting.release_to_wr,
tbl_wo_kitting.mpn,
m_product.m_product_id,
m_product.value,
m_product.name,
m_product.storelocator,
tbl_wo_project.wo_project_id,
tbl_wo_project.line_no AS project_line_no,
tbl_wo_project.quantity AS project_quantity,
m_transaction_moveqty_v.qtyonhand AS qtyonhand,
tbl_work_order.work_order_id,
tbl_work_order.reference_key,
case
when tbl_wo_kitting.level_no, = 'P+'
then '0'
else tbl_wo_kitting.level_no,
end as linenumber,
case
when tbl_wo_kitting.line_no_parent = 'PT+'
then '0'
else tbl_wo_kitting.line_no_parent
end as linenoparent
FROM (tbl_wo_kitting tbl_wo_kitting
INNER JOIN (m_product m_product
INNER JOIN m_transaction_moveqty_v m_transaction_moveqty_v
ON m_product.m_product_id = m_transaction_moveqty_v.m_product_id )
ON tbl_wo_kitting.m_product_id = m_product.m_product_id
INNER JOIN (tbl_wo_project tbl_wo_project
INNER JOIN tbl_work_order tbl_work_order
ON tbl_wo_project.work_order_id = tbl_work_order.work_order_id )
ON tbl_wo_kitting.wo_project_id = tbl_wo_project.wo_project_id )) AS TABLE1
ORDER BY tbl_wo_kitting.level_no, (string_to_array(linenoparent, '.'))::int[],(string_to_array(linenumber, '.'))::int[]
Any idea? This is selecting from PostgreSQL.
Thank you very much in advance.