I'm building a stored procedure for an ETL. With in the stored proc a table is created and the same table is used in the next query as two instances(using the same table with two aliases). Since the second query takes absurd amount of time I looked at the execution plans and executed the queries without the stored proc. When executed without the stored proc second query runs as expected in a reasonable amount of time.
Here are the two queries.
Query_1:
CREATE TABLE TMPRPT_STBDEX_SALE_BDM_$tblname (
SALE_JOURNAL_ID BIGINT(20) NULL DEFAULT NULL,
DEBTOR_CONSULTANT_RELATIONSHIP_ID INT(11) NULL DEFAULT '0',
DISPLAY_ORDER INT(11) NULL DEFAULT NULL,
INDEX IDX_SALE_JOURNAL_ID (SALE_JOURNAL_ID),
INDEX IDX_DEBCONS_ID (DEBTOR_CONSULTANT_RELATIONSHIP_ID),
INDEX IDX_DISPLAY_ORDER (DISPLAY_ORDER)
)
ENGINE=InnoDB
;
INSERT INTO TMPRPT_STBDEX_SALE_BDM_$tblname
SELECT DISTINCT
TSS.SALE_JOURNAL_ID,
RDC.DEBTOR_CONSULTANT_RELATIONSHIP_ID,
RDC.DISPLAY_ORDER
FROM
TMPRPT_STBDEX_SALE_BOOKING_$tblname TSS
LEFT OUTER JOIN BOOKING RB
ON (RB.BOOKING_ID = TSS.BOOKING_ID)
LEFT OUTER JOIN BOOKING_DEPT_LEVELS BDL
ON (BDL.BOOKING_ID = RB.BOOKING_ID)
LEFT OUTER JOIN TMPRPT_STBDEX_SEGMENT_$tblname RS
ON (RS.SEGMENT_ID = TSS.SEGMENT_ID)
LEFT OUTER JOIN DEBTOR_CONSULTANT_RELATIONSHIP RDC
ON (RDC.DEBTOR_ID = RB.DEBTOR_ID AND
RDC.CONSULTANT_ID IS NOT NULL AND
RDC.CONSULTANT_TYPE_CODE = 'BUSINESS_DEVELOPMENT' AND
RDC.COMMISSION_PERCENTAGE IS NOT NULL AND
(RDC.DOMESTIC_INTERNATIONAL_CODE = 'BOTH' OR CASE WHEN RDC.DOMESTIC_INTERNATIONAL_CODE = 'DOMESTIC' THEN 1 = RS.IDT_NUMBER ELSE 1 <> RS.IDT_NUMBER END ) AND
RDC.START_DATE <= TSS.TRANSACTION_DATE AND
(RDC.FINISH_DATE IS NULL OR RDC.FINISH_DATE >= TSS.TRANSACTION_DATE))
LEFT OUTER JOIN COST_CENTRE_DEBTOR_CONSULTANT_RELATIONSHIP CCDCR
ON (CCDCR.DEBTOR_CONSULTANT_RELATIONSHIP_ID = RDC.DEBTOR_CONSULTANT_RELATIONSHIP_ID AND CCDCR.COST_CENTRE_ID = RB.COST_CENTRE_ID)
LEFT OUTER JOIN DEPARTMENT_DEBTOR_CONSULTANT_RELATIONSHIP DDCR
ON (DDCR.DEBTOR_CONSULTANT_RELATIONSHIP_ID = RDC.DEBTOR_CONSULTANT_RELATIONSHIP_ID AND
(DDCR.DEPARTMENT_ID = BDL.LEVEL0 OR
DDCR.DEPARTMENT_ID = BDL.LEVEL1 OR
DDCR.DEPARTMENT_ID = BDL.LEVEL2 OR
DDCR.DEPARTMENT_ID = BDL.LEVEL3 OR
DDCR.DEPARTMENT_ID = BDL.LEVEL4 OR
DDCR.DEPARTMENT_ID = BDL.LEVEL5))
WHERE
(RDC.DISPLAY_ORDER = 1 OR RDC.DISPLAY_ORDER = 2) AND
(RDC.HAS_ALL_PERMISSION = 'Y' OR
(CCDCR.COST_CENTRE_ID IS NOT NULL AND DDCR.DEPARTMENT_ID IS NOT NULL));
Query_2:
SELECT
RSAL.SALE_JOURNAL_ID,
RS.COSTING_ID,
RD.DEBTOR_CODE,
CONCAT('B.',LPAD(CAST(RB.BOOKING_ID AS CHAR),10,'0')) AS BOOKING_REFERENCE,
RS.SEGMENT_ID,
DOC.DOCUMENT_REF_NUMBER AS INVOICE_NO,
RCON.NAME AS CONSULTANT_NAME,
COALESCE(RSPS.LEAD_PASSENGER_NAME, RCL.PROFILE_NAME) AS COSTING_PASSENGER,
RBR.CODE AS BRANCH_CODE,
RS.SEGMENT_SHORT_CODE,
(CASE WHEN RS.IDT_NUMBER = 1 THEN
'D'
WHEN RS.IDT_NUMBER = 2 THEN
'T'
WHEN RS.IDT_NUMBER = 3 THEN
'I'
ELSE NULL
END) AS DOM_INT,
(CASE WHEN RSAL.COSTING_PAYMENT_TYPE_CODE = 'PAY_DIRECT' THEN 0 ELSE
RSAL.SUPPLIER_RATES_EXCL_GST +
RSAL.SUPPLIER_RATES_GST_FREE +
RSAL.SUPPLIER_CHARGES_EXCL_COMMISSION +
RSAL.SUPPLIER_CHARGES_COMMISSION_FREE +
RSAL.SUPPLIER_FEES_EXCL_GST +
RSAL.TAX_AMOUNT_EXCL_GST_CALCULATED +
RSAL.TAX_AMOUNT_GST_FREE +
RSAL.AGENCY_MARKUP_EXCL_GST_CALCULATED +
RSAL.AGENCY_DISCOUNT_EXCL_GST_CALCULATED
END) AS GROSS_SALES,
(CASE WHEN RSAL.COSTING_PAYMENT_TYPE_CODE = 'PAY_DIRECT' THEN
RSAL.SUPPLIER_RATES_EXCL_GST +
RSAL.SUPPLIER_RATES_GST_FREE +
RSAL.SUPPLIER_CHARGES_EXCL_COMMISSION +
RSAL.SUPPLIER_CHARGES_COMMISSION_FREE +
RSAL.SUPPLIER_FEES_EXCL_GST +
RSAL.TAX_AMOUNT_EXCL_GST_CALCULATED +
RSAL.TAX_AMOUNT_GST_FREE +
RSAL.AGENCY_MARKUP_EXCL_GST_CALCULATED +
RSAL.AGENCY_DISCOUNT_EXCL_GST_CALCULATED
ELSE 0 END) AS PD_SALES,
(CASE WHEN RSAL.COSTING_PAYMENT_TYPE_CODE = 'PAY_DIRECT' THEN 0 ELSE RSAL.SERVICES_CREDITOR_COMMISSION_AMOUNT_EXCL_GST_CALCULATED - (RS.COSTING_MERCHANT_FEE_POSTED_EXCL_GST * (SIGN(RSAL.SERVICES_CREDITOR_COMMISSION_AMOUNT_EXCL_GST_CALCULATED + RSAL.SUPPLIER_RATES_EXCL_GST))) END) AS EARNED_COMM,
(CASE WHEN RSAL.COSTING_PAYMENT_TYPE_CODE = 'PAY_DIRECT' THEN RSAL.SERVICES_CREDITOR_COMMISSION_AMOUNT_EXCL_GST_CALCULATED - (RS.COSTING_MERCHANT_FEE_POSTED_EXCL_GST * (SIGN(RSAL.SERVICES_CREDITOR_COMMISSION_AMOUNT_EXCL_GST_CALCULATED + RSAL.SUPPLIER_RATES_EXCL_GST))) ELSE 0 END) AS PD_COMM,
RSAL.OVERRIDE_AMOUNT_POSTED_EXCL_GST AS OVERRIDE_COMM,
(CASE
WHEN RDMF.DEBTOR_MANAGEMENT_FEE_ID IS NULL THEN 0
WHEN RDMF.FEE_AMOUNT_TYPE = 'PERCENTAGE'
THEN
(RDMF.FEE_AMOUNT / 100.00) *
(RSAL.SUPPLIER_RATES_EXCL_GST +
RSAL.SUPPLIER_RATES_GST_FREE +
RSAL.SUPPLIER_CHARGES_EXCL_COMMISSION +
RSAL.SUPPLIER_CHARGES_COMMISSION_FREE)
WHEN RDMF.FEE_AMOUNT_TYPE = 'DOLLAR_INCL_GST'
THEN (RDMF.FEE_AMOUNT / ((100.00 + RAGN.GST_PERCENTAGE) / 100.00))
ELSE
RDMF.FEE_AMOUNT
END) AS RETENTIONS,
(RS.COSTING_SPECULATIVE_MERCHANT_FEE_POSTED_EXCL_GST * SIGN(RSAL.SERVICES_CREDITOR_COMMISSION_AMOUNT_EXCL_GST_CALCULATED + RSAL.SUPPLIER_RATES_EXCL_GST)) AS MERCHANT_FEE,
CONS.NAME AS BDM1_NAME,
RDC.COMMISSION_PERCENTAGE AS BDM1_PERCENTAGE,
CONS2.NAME AS BDM2_NAME,
RDC2.COMMISSION_PERCENTAGE AS BDM2_PERCENTAGE
FROM
TMPRPT_STBDEX_SALE_BOOKING_$tblname TSS
LEFT OUTER JOIN SALE_JOURNAL RSAL
ON (RSAL.SALE_JOURNAL_ID = TSS.SALE_JOURNAL_ID)
LEFT OUTER JOIN AGENCY RAGN
ON (RAGN.AGENCY_ID = 1)
LEFT OUTER JOIN TMPRPT_STBDEX_SEGMENT_$tblname RS
ON (RS.COSTING_ID = RSAL.COSTING_ID)
LEFT OUTER JOIN BOOKING RB
ON (RB.BOOKING_ID = RS.BOOKING_ID)
LEFT OUTER JOIN DEBTOR RD
ON (RD.DEBTOR_ID = RB.DEBTOR_ID)
LEFT OUTER JOIN TRANSACTION_JOURNAL RTJ
ON (RTJ.TRANSACTION_JOURNAL_ID = RSAL.TRANSACTION_JOURNAL_ID)
LEFT OUTER JOIN TRANSACTION_JOURNAL_LINKS TJL
ON (TJL.TRANSACTION_JOURNAL_ID = RTJ.TRANSACTION_JOURNAL_ID)
LEFT OUTER JOIN INVOICE RI
ON (RI.INVOICE_ID = TJL.INVOICE_ID)
LEFT OUTER JOIN DOCUMENT DOC
ON (RI.DOCUMENT_ID = DOC.DOCUMENT_ID)
LEFT OUTER JOIN CONSULTANT RCON
ON (RCON.CONSULTANT_ID = RB.PREF_CONSULTANT1_ID)
LEFT OUTER JOIN SEGMENT_PASSENGER_SUMMARY RSPS
ON (RSPS.SEGMENT_ID = RS.SEGMENT_ID)
LEFT OUTER JOIN BRANCH RBR
ON (RBR.BRANCH_ID = RB.LVL1_BRANCH_ID)
LEFT OUTER JOIN CLIENT RCL
ON (RCL.CLIENT_ID = RB.CLIENT_ID)
LEFT OUTER JOIN DEBTOR_MANAGEMENT_FEE RDMF
ON (RDMF.DEBTOR_ID = RD.DEBTOR_ID AND
RDMF.SEGMENT_TYPE = RS.SEGMENT_TYPE_CODE AND
(RDMF.AIRLINE_CODE = RS.AIR_AIRLINE_CODE OR RDMF.SEGMENT_TYPE <> 'TICKET') AND
(RDMF.INT_DOM = CASE WHEN RS.IDT_NUMBER = 1 THEN 'DOMESTIC' ELSE 'INTERNATIONAL' END) AND
(RDMF.TERMINATION_DATE IS NULL OR RDMF.TERMINATION_DATE > CURDATE()))
LEFT OUTER JOIN TMPRPT_STBDEX_SALE_BDM_$tblname TSSB
ON (TSSB.SALE_JOURNAL_ID = RSAL.SALE_JOURNAL_ID AND TSSB.DISPLAY_ORDER = 1)
LEFT OUTER JOIN DEBTOR_CONSULTANT_RELATIONSHIP RDC
ON (RDC.DEBTOR_CONSULTANT_RELATIONSHIP_ID = TSSB.DEBTOR_CONSULTANT_RELATIONSHIP_ID AND
(RDC.CONSULTANT_ID = ParamBDMConsultant OR ParamBDMConsultant IS NULL))
LEFT OUTER JOIN CONSULTANT CONS ON (CONS.CONSULTANT_ID = RDC.CONSULTANT_ID)
LEFT OUTER JOIN TMPRPT_STBDEX_SALE_BDM_$tblname TSSB2
ON (TSSB2.SALE_JOURNAL_ID = RSAL.SALE_JOURNAL_ID AND TSSB2.DISPLAY_ORDER = 2)
LEFT OUTER JOIN DEBTOR_CONSULTANT_RELATIONSHIP RDC2
ON (RDC2.DEBTOR_CONSULTANT_RELATIONSHIP_ID = TSSB2.DEBTOR_CONSULTANT_RELATIONSHIP_ID AND
(RDC2.CONSULTANT_ID = ParamBDMConsultant OR ParamBDMConsultant IS NULL))
LEFT OUTER JOIN CONSULTANT CONS2 ON (CONS2.CONSULTANT_ID = RDC2.CONSULTANT_ID)
WHERE
(ParamBDMConsultant IS NULL OR RDC.CONSULTANT_ID = ParamBDMConsultant) AND
(ParamExcludeCostingsWithoutBDM = 'No' OR RDC.CONSULTANT_ID IS NOT NULL)
GROUP BY
RSAL.SALE_JOURNAL_ID;
Note that TMPRPT_STBDEX_SALE_BDM_$tblname created in Query_1 is used twice in Query_2.
Below are the execution plans for Query_2
Execution Plan for Query_2 when executed with in stored proc
Execution Plan for Query_2 when executed manually with out stored proc
Note the highlighted lines where Table created in Query_1 is involved. I don't understand why it's scanning the entire table when type is ref and proper index is identified.
I was able to get this resolved by changing how the index is created for table in Query_1 to an Alter table add index index_name after the table is populated, and that solved my problem.
Also able to get this resolved by separating the data set in Query_1 into two tables and use them in place of the single table in Query_2.
For me it seemed like mysql doesn't pick the proper execution plan due to a delay in gathering stats.
Can someone explain why this is happening?
Mysql version: 5.6
Related
I have the following sentence, that returns the error
Unknown column targets.ID_TARGET in where clause
and I can't find any solution. Could you guys help?
The proposal is update 'sw_automatic' for each row with the value that th subquery provides (0 or 1)
update bt_pry_targets targets
set targets.sw_automatic = (
(
SELECT (CASE WHEN Task.ID_TP_TASKS_GROUPS = 694 THEN '0' ELSE '1' END) AS TYPE_TASK,
Task.ID_TASK FROM bt_tasks AS Task
INNER JOIN bt_pry_cmp_workflows AS BtCmpWorkflows ON (Task.ID_PRY_CMP_WORKFLOW = BtCmpWorkflows.ID_PRY_CMP_WORKFLOW)
INNER JOIN bt_pry_components AS PryComponent ON (PryComponent.ID_PRY_COMPONENT = BtCmpWorkflows.ID_PRY_COMPONENT )
INNER JOIN bt_components AS Component ON (PryComponent.ID_COMPONENT = Component.ID_COMPONENT)
INNER JOIN bt_pry_targets AS PryTarget ON (PryComponent.ID_TARGET = PryTarget.ID_TARGET)
INNER JOIN bt_flows AS Flows ON (Flows.ID_FLOW = Task.ID_FLOW)
WHERE Flows.SW_END_DEPENDENCE = 1
AND PryTarget.ID_TARGET = targets.ID_TARGET
GROUP BY Task.ID_TASK) )
where targets.sw_automatic is null;
In you subquery the column targets.ID_TARGET in not visible
so you could try using you subquery as a join table for updated
update bt_pry_targets targets
inner join (
SELECT (CASE WHEN Task.ID_TP_TASKS_GROUPS = 694 THEN '0' ELSE '1' END) AS TYPE_TASK,
Task.ID_TASK FROM bt_tasks AS Task
INNER JOIN bt_pry_cmp_workflows AS BtCmpWorkflows ON (Task.ID_PRY_CMP_WORKFLOW = BtCmpWorkflows.ID_PRY_CMP_WORKFLOW)
INNER JOIN bt_pry_components AS PryComponent ON (PryComponent.ID_PRY_COMPONENT = BtCmpWorkflows.ID_PRY_COMPONENT )
INNER JOIN bt_components AS Component ON (PryComponent.ID_COMPONENT = Component.ID_COMPONENT)
INNER JOIN bt_pry_targets AS PryTarget ON (PryComponent.ID_TARGET = PryTarget.ID_TARGET)
INNER JOIN bt_flows AS Flows ON (Flows.ID_FLOW = Task.ID_FLOW)
WHERE Flows.SW_END_DEPENDENCE = 1
AND PryTarget.ID_TARGET = targets.ID_TARGET
GROUP BY Task.ID_TASK
) t on t.PryTarget = targets.ID_TARGET
AND targets.sw_automatic is null
set targets.sw_automatic = t.TYPE_TASK
First question on here, so I apologise if I have missed something previously asked, or don't format this well....
My company has a custom CRM + database that I am attempting to improve. We need to find a list of properties that will not have their yearly service renewed. Currently, we do this by first finding properties that will have their service renewed, which is done with the following query:
SELECT DISTINCT
j.`property_id`
FROM
`jobs` AS j
LEFT JOIN `property` AS p
ON j.`property_id` = p.`property_id`
LEFT JOIN `agency` AS a
ON p.`agency_id` = a.`agency_id`
INNER JOIN `property_services` AS ps
ON (
j.`property_id` = ps.`property_id`
AND j.`service` = ps.`alarm_job_type_id`
)
WHERE ps.`service` = 1
AND a.`country_id` = 1
AND (
j.`status` = 'Pending'
OR j.`date` IS NULL
OR j.`date` = '0000-00-00'
OR j.`job_type` = 'Once-off'
OR j.`job_type` = '240v Rebook'
OR (
j.`date` >= '2019-04-22'
AND j.`job_type` = 'Yearly Maintenance'
)
)
Then we find the details we want to display for the user, excluding other items in the process:
SELECT DISTINCT
j.`property_id`,
p.`address_1` AS p_address1,
p.`address_2` AS p_address2,
p.`address_3` AS p_address3,
p.`state` AS p_state,
p.`postcode` AS p_postcode,
a.`agency_id`,
a.`agency_name`
FROM
`jobs` AS j
LEFT JOIN `property` AS p
ON j.`property_id` = p.`property_id`
LEFT JOIN `agency` AS a
ON p.`agency_id` = a.`agency_id`
INNER JOIN `property_services` AS ps
ON (
j.`property_id` = ps.`property_id`
AND j.`service` = ps.`alarm_job_type_id`
)
WHERE p.`property_id` NOT IN (INSERT HERE THE IDS YOU GOT FROM THE FIRST QUERY)
AND ps.`service` = 1
AND p.`deleted` = 0
AND p.`agency_deleted` = 0
AND a.`status` = 'active'
AND a.`country_id` = 1
ORDER BY j.`property_id` DESC
LIMIT 0, 50
Ideally, I'd like to combine these queries, or somehow optimise them, as the page currently takes 2+ minutes to load, even with indexing.
Again, my apologies, I am not a database or query expert, pretty sure the degree only included one or two subjects on the matter!
For the record (in case someone would find it helpful), the combined version is:
SELECT DISTINCT
j.`property_id`,
p.`address_1` AS p_address1,
p.`address_2` AS p_address2,
p.`address_3` AS p_address3,
p.`state` AS p_state,
p.`postcode` AS p_postcode,
a.`agency_id`,
a.`agency_name`
FROM
`jobs` AS j
LEFT JOIN `property` AS p
ON j.`property_id` = p.`property_id`
LEFT JOIN `agency` AS a
ON p.`agency_id` = a.`agency_id`
INNER JOIN `property_services` AS ps
ON (
j.`property_id` = ps.`property_id`
AND j.`service` = ps.`alarm_job_type_id`
)
WHERE p.`property_id` NOT IN
(SELECT DISTINCT
j.`property_id`
FROM
`jobs` AS j
LEFT JOIN `property` AS p
ON j.`property_id` = p.`property_id`
LEFT JOIN `agency` AS a
ON p.`agency_id` = a.`agency_id`
INNER JOIN `property_services` AS ps
ON (
j.`property_id` = ps.`property_id`
AND j.`service` = ps.`alarm_job_type_id`
)
WHERE ps.`service` = 1
AND a.`country_id` = 1
AND (
j.`status` = 'Pending'
OR j.`date` IS NULL
OR j.`date` = '0000-00-00'
OR j.`job_type` = 'Once-off'
OR j.`job_type` = '240v Rebook'
OR (
j.`date` >= '2019-05-08'
AND j.`job_type` = 'Yearly Maintenance'
)
))
AND ps.`service` = 1
AND p.`deleted` = 0
AND p.`agency_deleted` = 0
AND a.`status` = 'active'
AND a.`country_id` = 1
AND (
j.`status` != 'Booked'
AND j.`status` != 'To Be Booked'
AND j.`status` != 'Send Letters'
AND j.`status` != 'On Hold'
AND j.`status` != 'On Hold - COVID'
AND j.`status` != 'Pre Completion'
AND j.`status` != 'Merged Certificates'
)
AND j.`date` > DATE_ADD(NOW(), INTERVAL - 350 DAY)
ORDER BY j.`property_id` DESC
Someone outside of StackOverflow helped combine, but it didn't help...
We ended up having to add a marker and search for that, because this query took 193 seconds to run on our database.
Also, I totally get the requirement to provide a minimum reproducible example, and its my fault for not doing that.
I am using InnoDB. From this question, I found out that I have to specify the length if I want to add index to columns which type is TEXT.
But after successfully adding index, the performance for the select query stay the same. Anyone know why? I did check the index with show index from tableName and the index did exist.
So it was the last two table EventResultsFinalSummary and EventResultsPrelims.
CREATE OR REPLACE VIEW ScheduleView AS
SELECT s.ScheduleID, e.EventRound, e.EventRoundsID, e.EventID, e.NumberCouplesInRound, n.NumberOnBack, eic.EventName AS 'Division',
CONCAT(a1.FirstName, ' ', a1.LastName, ' - ', a2.FirstName, ' ', a2.LastName) AS 'Couple',
s.SessionID AS 'Session', erfs.CouplePlace, c.CoupleID,
s.Timeslot, s.SubFloor ,s.itemDuration,s.HeatNumber, o.ActivityName, st.StudioName AS 'DanceStudio', a.AgeName AS 'Age', s.competition_id, erp.CoupleVotes
FROM Schedule AS s
LEFT JOIN EventRounds AS e ON s.EventRoundID = e.EventRoundsID AND s.competition_id = e.competition_id
LEFT JOIN OtherActivities AS o ON s.OtherActivitiesID = o.OtherActivitiesID AND s.competition_id = o.competition_id
LEFT JOIN EntriesEvents AS ee ON e.EventID = ee.EventID AND e.EventRound <= ee.EventRound AND e.Competition_id = ee.Competition_id
LEFT JOIN Couples AS c ON ee.EntryID = c.CoupleID AND ee.Competition_id = c.Competition_id
LEFT JOIN NumSysComps AS n ON c.CompetitorIDMan = n.CompetitorIDMan AND c.Competition_id = n.Competition_id
LEFT JOIN Attendees AS a1 ON c.CompetitorIDMan = a1.AttendeeID AND c.Competition_id = a1.Competition_id
LEFT JOIN Attendees AS a2 ON c.CompetitorIDLady = a2.AttendeeID AND c.Competition_id = a2.Competition_id
LEFT JOIN Studios AS st ON a1.StudioID = st.StudioID AND a1.Competition_id = st.Competition_id
LEFT JOIN EventsInComp AS eic ON eic.EventID = e.EventID AND eic.Competition_id = e.Competition_id
LEFT JOIN ProAmSingleDanceEvents AS psd ON eic.ProAmSingleDanceEventID = psd.ProAmSingleDanceEventID AND eic.Competition_id = psd.Competition_id
LEFT JOIN ProAmMultiDanceEvents AS pmd ON eic.ProAmMultiDanceEventID = pmd.ProAmMultiDanceEventID AND eic.Competition_id = pmd.Competition_id
LEFT JOIN Ages AS a ON (
psd.AgeID = a.AgeID AND psd.Competition_id = a.Competition_id
OR
pmd.AgeID = a.AgeID AND pmd.Competition_id = a.Competition_id
)
LEFT JOIN EventResultsFinalSummary AS erfs ON e.EventID = erfs.EventID AND c.CoupleID = erfs.CoupleID AND s.Competition_id = erfs.Competition_id
LEFT JOIN EventResultsPrelims AS erp ON e.EventID = erp.EventID AND erp.EventRound = e.EventRound AND c.CoupleID = erp.CoupleID AND s.Competition_id = erp.Competition_id
ORDER BY s.ScheduleID;
I added index to the column that I joined.
EventID, CoupleId, Competition_id for EventResultsFinalSummary and EventID, EventRound, Competition_id for EventResultsPrelims by using query like following.
My question is that when those columns have type like varchar or int, the select * query will only take 1s. But it take 26s when the type is Text.
ALTER TABLE `EventResultsPrelims` ADD INDEX(`EventID`(6));
I have a principal requet with 2 requets in. I have a problem in my second nested query, I have a condition on id and if I made my request id = 10 takes a long time to execute, so if I replace it by id LIKE 10 my request execute in one second.
Here the request:
SELECT SQL_NO_CACHE contact_groupe.id_contact_groupe
FROM toto.contact_groupe
LEFT JOIN toto.`contact` AS `contact`
ON ((toto.contact_groupe.id_contact_groupe = toto.contact.id_contact_groupe))
LEFT JOIN toto.`project` AS `project`
ON ((toto.contact_groupe.id_contact_groupe = toto.project.id_contact_groupe)
AND ( toto.project.id_project
IN (
SELECT MAX(toto.project.id_project)
FROM toto.project
WHERE ( toto.contact_groupe.id_contact_groupe = toto.project.id_contact_groupe )
) ))
LEFT JOIN toto.`phase` AS `phase`
ON ((project.id_phase = toto.phase.id_phase))
LEFT JOIN sql_base.`user` AS `user_suivi`
ON ((toto.contact_groupe.id_user_suivi = user_suivi.id_user))
WHERE ( en_attente = '0' AND contact_groupe.id_contact_groupe
IN (
SELECT DISTINCT(contact_groupe.id_contact_groupe)
FROM toto.contact_groupe
LEFT JOIN toto.`contact` AS `contact`
ON ((toto.contact_groupe.id_contact_groupe = toto.contact.id_contact_groupe)
LEFT JOIN toto.`source_contact_groupe` AS `source_contact_groupe`
ON ((toto.contact_groupe.id_contact_groupe = toto.source_contact_groupe.id_contact_groupe))
LEFT JOIN toto.`project` AS `project`
ON ((toto.contact_groupe.id_contact_groupe = toto.project.id_contact_groupe))
LEFT JOIN toto.`remarque` AS `remarque`
ON ((toto.contact_groupe.id_contact_groupe = toto.remarque.id_contact_groupe))
LEFT JOIN toto.`project_type_construction_options` AS `project_type_construction_options`
ON ((project.id_project = toto.project_type_construction_options.id_project))
LEFT JOIN toto.`project_concurrent` AS `project_concurrent`
ON ((project.id_project = toto.project_concurrent.id_project))
LEFT JOIN toto.`telephone` AS `telephone`
ON ((contact.id_contact = toto.telephone.id_contact))
WHERE ( en_attente = '0' AND ( toto.project.id_project = '10' ) AND toto.contact_groupe.id_entreprise = '2' )
)
AND toto.contact_groupe.id_entreprise = '2' )
ORDER BY toto.contact_groupe.id_contact_groupe ASC
the line is the following problem toto.project.id_project = '10' and I don't understand why the time to execute request is so different between = and LIKE
Let's start with your subquery. Those 17 lines that you've written are functionally identical to this, so why not use this instead?
SELECT DISTINCT g.id_contact_groupe
FROM contact_groupe g
JOIN project p
ON p.id_contact_groupe = g.id_contact_groupe
WHERE g.en_attente = 0
AND p.id_project = 10
AND g.id_entreprise = 2
The following query on my MySQL tables returns rows from the purchaseorder table that have corresponding entries in the deliveryorder table. How do I construct this query so that I get rows from the purchaseorder table even if no corresponding rows exist in the deliveryorder table? If the users want to see sql table CREATE statements, I can post those, but I'm not posting now as it really makes the question too big.
SELECT
`purchaseorder`.`id` AS `po_id`,
`purchaseorder`.`order_quantity` AS `po_order_quantity`,
`purchaseorder`.`applicable_approved_unit_rate` AS `po_unit_rate`,
`purchaseorder`.`applicable_sales_tax_rate` AS `po_tax_rate`,
`purchaseorder`.`order_date` AS `po_order_date`,
`purchaseorder`.`remarks` AS `po_remarks`,
`purchaseorder`.`is_open` AS `po_is_open`,
`purchaseorder`.`is_active` AS `po_is_active`,
`purchaseorder`.`approved_rate_id` AS `po_app_rate_id`,
`supplier`.`name` AS `sup_name`,
SUM(`deliveryorder`.`quantity`) AS `total_ordered`
FROM `purchaseorder`
LEFT JOIN `deliveryorder` ON (`deliveryorder`.`purchase_order_id` = `purchaseorder`.`id`)
INNER JOIN `approvedrate` ON (`purchaseorder`.`approved_rate_id` = `approvedrate`.`id`)
INNER JOIN `supplier` ON (`approvedrate`.`supplier_id` = `supplier`.`id`)
WHERE (
`purchaseorder`.`is_active` = 1
AND `purchaseorder`.`is_open` = 1
AND `deliveryorder`.`is_active` = 1
AND `approvedrate`.`material_id` = 2
)
HAVING `purchaseorder`.`order_quantity` >= `total_ordered` + 1
You have an aggregating function but no GROUP BY clause, which is wierd, but anyway - something like this? Oops - edited...
SELECT po.id po_id
, po.order_quantity po_order_quantity
, po.applicable_approved_unit_rate po_unit_rate
, po.applicable_sales_tax_rate po_tax_rate
, po.order_date po_order_date
, po.remarks po_remarks
, po.is_open po_is_open
, po.is_active po_is_active
, po.approved_rate_id po_app_rate_id
, s.name sup_name
, SUM(do.quantity) total_ordered
FROM purchaseorder po
LEFT
JOIN deliveryorder do
ON do.purchase_order_id = po.
AND do.is_active = 1
LEFT
JOIN approvedrate ar
ON ar.id = po.approved_rate_id
AND ar.material_id = 2
LEFT
JOIN supplier s
ON s.id = ar.supplier_id
WHERE po.is_active = 1
AND po.is_open = 1
HAVING po.order_quantity >= total_ordered + 1
I couldn't work out how to get the desired results all in one query, but ended up using the following two queries to fulfill my requirements: -
1st query
SELECT
pot.`id` AS `po_id`,
pot.`order_quantity` AS `po_order_quantity`,
pot.`applicable_approved_unit_rate` AS `po_unit_rate`,
pot.`applicable_sales_tax_rate` AS `po_tax_rate`,
pot.`is_open` AS `po_is_open`,
pot.`is_active` AS `po_is_active`,
st.`id` AS `sup_id`,
st.`name` AS `sup_name`,
SUM(dot.`quantity`) AS `total_ordered`
FROM `purchaseorder` pot
INNER JOIN `deliveryorder` dot ON (dot.`purchase_order_id` = pot.`id`)
INNER JOIN `approvedrate` art ON (pot.`approved_rate_id` = art.`id`)
INNER JOIN `supplier` st ON (art.`supplier_id` = st.`id`)
WHERE (
pot.`is_active` = 1
AND pot.`is_open` = 1
AND art.`material_id` = #materialid
AND art.`in_effect` = 1
AND art.`is_active` = 1
AND dot.`is_active` = 1
AND st.`is_active` = 1
)
HAVING pot.`order_quantity` >= `total_ordered` + #materialquantity
2nd query
SELECT
pot.`id` AS `po_id`,
pot.`order_quantity` AS `po_order_quantity`,
pot.`applicable_approved_unit_rate` AS `po_unit_rate`,
pot.`applicable_sales_tax_rate` AS `po_tax_rate`,
pot.`is_open` AS `po_is_open`,
pot.`is_active` AS `po_is_active`,
st.`id` AS `sup_id`,
st.`name` AS `sup_name`,
0 AS `total_ordered`
FROM `purchaseorder` pot
INNER JOIN `approvedrate` art ON (pot.`approved_rate_id` = art.`id`)
INNER JOIN `supplier` st ON (art.`supplier_id` = st.`id`)
WHERE (
pot.`is_active` = 1
AND pot.`is_open` = 1
AND art.`material_id` = #materialid
AND art.`in_effect` = 1
AND art.`is_active` = 1
AND st.`is_active` = 1
AND pot.`order_quantity` >= #materialquantity
AND pot.`id` NOT IN
(
SELECT dot.`purchase_order_id`
FROM `deliveryorder` dot
WHERE dot.is_active = 1
)
)