SQLite Forum

Help speeding up this query
Login
The conditions in the WHERE clause make the LEFT superfluous and the ON conditions duplicitous.

Remove the word LEFT and the entire ON conditions (the duplicate conditions), change the first AND to WHERE and the last WHERE to AND.

```
SELECT a.*,b.*,c.*
  FROM Project_List AS a 
  JOIN Project_Dashboard AS b
  JOIN Project_Extras AS c
  WHERE
    a.PMO_Board_Report != 'No' 
  AND
    a.Status = 'Acknowledged' 
  AND
    Project_Type != 'Outside IT perimeter'
  AND
    a.Start_date < date('now')
  AND
  (
    (a.Target_Go_Live_Date > substr(date('now'),1,4) || '-01-15') OR
    (a.Target_Go_Live_Date = '' AND a.Finish_Date >  substr(date('now'),1,4) || '-01-15')
  )
  AND
  (
    b.TimeIndicator = '0'
    OR
    b.CostIndicator = '0'
  )
  AND
    a.InsertDate = 
      (SELECT MAX(InsertDate) FROM Project_List WHERE a.ProjID = ProjID)
  AND
    b.InsertDate = 
      (SELECT MAX(InsertDate) FROM Project_Dashboard WHERE b.ProjID = ProjID)
  AND
    c.InsertDate = 
      (SELECT MAX(InsertDate) FROM Project_Extras WHERE c.ProjID = ProjID)
  AND a.ProjID = b.ProjID 
  AND a.ProjID = c.ProjID 
group BY a.Manager, a.ProjID
ORDER BY a.Manager, a.ProjID
;
```

Whats killing you is the three correlated subqueries.  You need to generate those into a materialized view first and then use that in the query.  Eg:

```
with maxes(ProjID, pl_insert, pd_insert, pe_insert)
  as (
      select projid,
             max(InsertDate),
             (select max(insertdate) from project_dashboard where ProjID = e.projID),
             (select max(insertdate) from project_extras where projid = e.projid)
        from project list e
    group by projid
     )
SELECT a.*,b.*,c.*
  FROM Project_List AS a 
  JOIN Project_Dashboard AS b
  JOIN Project_Extras AS c
  JOIN maxes
  WHERE
    a.PMO_Board_Report != 'No' 
  AND
    a.Status = 'Acknowledged' 
  AND
    Project_Type != 'Outside IT perimeter'
  AND
    a.Start_date < date('now')
  AND
  (
    (a.Target_Go_Live_Date > substr(date('now'),1,4) || '-01-15') OR
    (a.Target_Go_Live_Date = '' AND a.Finish_Date >  substr(date('now'),1,4) || '-01-15')
  )
  AND
  (
    b.TimeIndicator = '0'
    OR
    b.CostIndicator = '0'
  )
  AND
    a.InsertDate = maxes.pl_insert
  AND
    b.InsertDate = maxes.pd_insert
  AND
    c.InsertDate = maxes.pe_insert
  AND a.ProjID = b.ProjID 
  AND a.ProjID = c.ProjID 
  AND a.projid = maxes.projid
group BY a.Manager, a.ProjID
ORDER BY a.Manager, a.ProjID
;
```

And then you need to "fiddle" to make sure that the subquery "maxes" is getting materialized (if it does not get materialized as is, then maybe making it uselessly DISTINCT (as in SELECT DISTINCT ...) will do it.