I have the following query, and because of a lot of SUM
function calls, my query is running too slow. I have a lot of records in my database and I would like to get
I assume tb1 is a large table (relative to tb2, tb3, tb4 and tb5).
If so, it makes sense here to restrict the selection of that table (with a WHERE clause).
If only a small part of tb1 is used, for example because the joins with tb2, tb3, tb4 and tb5 reduce the needed rows to just a few percent, then you should check if the tables are indexed on the columns you use in the joins.
If a large part of tb1 is used, then it can make sense to group its results before joining it to tb2, tb3, tb4 and tb5. Below is an example of that.
SELECT
b.id as [ID]
,d.[Title] as [Title]
,e.Class as [Class]
,SUM(a.[Current - Last 30 Days Col1]) AS [Current - Last 30 Days Col1]
,SUM(a.[Current - Last 30 Days Col2]) AS [Current - Last 30 Days Col2]
,SUM(a.[Current - Last 90 Days Col1]) AS [Current - Last 90 Days Col1]
-- etc.
FROM (
SELECT a.id, a.col3
,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 30 Days Col1]
,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 30 Days Col2]
,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 90 Days Col1]
,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 90 Days Col2]
,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Current - Last 365 Days Col1]
,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Current - Last 365 Days Col2]
,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 30 Days Col1]
,Sum(CASE WHEN a.DateCol >= DATEADD(MONTH,-13,GETDATE()) and a.DateCol <= DATEADD(MONTH,-12,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 30 Days Col2]
,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 90 Days Col1]
,Sum(CASE WHEN a.DateCol >= DATEADD(QUARTER,-5,GETDATE()) and a.DateCol <= DATEADD(QUARTER,-4,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 90 Days Col2]
,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col1 ELSE 0 END) as [Last year - Last 365 Days Col1]
,Sum(CASE WHEN a.DateCol >= DATEADD(YEAR,-2,GETDATE()) and a.DateCol <= DATEADD(YEAR,-1,GETDATE()) THEN a.col2 ELSE 0 END) as [Last year - Last 365 Days Col2]
FROM tb1 a
WHERE a.DateCol >= DATEADD(YEAR,-2,GETDATE())
GROUP BY a.id, a.col3
) AS a
INNER JOIN
tb2 b on a.id=b.fid and a.col3 = b.col4
INNER JOIN
tb3 c on b.fid = c.col5
INNER JOIN
tb4 d on c.id = d.col6
INNER JOIN
tb5 e on c.col7 = e.id
GROUP BY
b.id, d.Title, e.Class
To improve the speed of SQL query, you must add indexes. For each joined table, you have to add one index.
Like this code example for oracle:
CREATE INDEX supplier_idx
ON supplier (supplier_name);