Aggiornamento: riceverò il piano di query non appena possibile.L'aggiunta di Condizionale attorno alla query aumenta il tempo di oltre il 2400%
Abbiamo avuto una query con scarse prestazioni che ha richiesto 4 minuti per una particolare organizzazione. Dopo la consueta ricompilazione delle statistiche memorizzate di proc e di aggiornamento non è stato d'aiuto, abbiamo riscritto il if Exists (...) in un conteggio selezionato (*) ... e la stored procedure da 4 minuti a 70 millisecondi. Qual è il problema con il condizionale che rende una query di 70 ms impiega 4 minuti? Vedi gli esempi
Questi tutti prendono 4+ minuti:
if (
SELECT COUNT(*)
FROM ObservationOrganism omo
JOIN Observation om ON om.ObservationID = omo.ObservationMicID
JOIN Organism o ON o.OrganismID = omo.OrganismID
JOIN ObservationMicDrug omd ON omd.ObservationOrganismID = omo.ObservationOrganismID
JOIN SIRN srn ON srn.SIRNID = omd.SIRNID
JOIN OrganismDrug od ON od.OrganismDrugID = omd.OrganismDrugID
WHERE
om.StatusCode IN ('F', 'C')
AND o.OrganismGroupID <> -1
AND od.OrganismDrugGroupID <> -1
AND (om.LabType <> 'screen' OR om.LabType IS NULL)) > 0
print 'records';
-
IF (EXISTS(
SELECT *
FROM ObservationOrganism omo
JOIN Observation om ON om.ObservationID = omo.ObservationMicID
JOIN Organism o ON o.OrganismID = omo.OrganismID
JOIN ObservationMicDrug omd ON omd.ObservationOrganismID = omo.ObservationOrganismID
JOIN SIRN srn ON srn.SIRNID = omd.SIRNID
JOIN OrganismDrug od ON od.OrganismDrugID = omd.OrganismDrugID
WHERE
om.StatusCode IN ('F', 'C')
AND o.OrganismGroupID <> -1
AND od.OrganismDrugGroupID <> -1
AND (om.LabType <> 'screen' OR om.LabType IS NULL))
print 'records'
Tutto questo prende 70 millisecondi:
Declare @recordCount INT;
SELECT @recordCount = COUNT(*)
FROM ObservationOrganism omo
JOIN Observation om ON om.ObservationID = omo.ObservationMicID
JOIN Organism o ON o.OrganismID = omo.OrganismID
JOIN ObservationMicDrug omd ON omd.ObservationOrganismID = omo.ObservationOrganismID
JOIN SIRN srn ON srn.SIRNID = omd.SIRNID
JOIN OrganismDrug od ON od.OrganismDrugID = omd.OrganismDrugID
WHERE
om.StatusCode IN ('F', 'C')
AND o.OrganismGroupID <> -1
AND od.OrganismDrugGroupID <> -1
AND (om.LabType <> 'screen' OR om.LabType IS NULL);
IF(@recordCount > 0)
print 'records';
Non ha senso per me perché spostare la stessa query Count(*)
in un'istruzione if provoca una tale degradazione o perché "Esiste" è più lento di Count
. Ho anche provato il exists()
in un select CASE WHEN Exists()
ed è ancora 4+ minuti.
Hai esaminato i piani di query? –
Puoi pubblicare i piani di query tra i tre esempi? –
typo in last query? Una parentesi non chiusa in 'AND (om.LabType <> 'schermo' O om.LabType È NULL;' – Ingaz