Reputation: 6246
I have the following query:
SELECT table2.serialcode,
p.name,
date,
power,
behind,
direction,
length,
centerlongitude,
centerlatitude,
currentlongitude,
currentlatitude
FROM table1 as table2
JOIN pivots p ON p.serialcode = table2.serial
WHERE table2.serialcode = '49257'
and date = (select max(a.date) from table1 a where a.serialcode ='49257');
It seems it is retrieving the select max subquery for each join. It takes a lot of time. Is there a way to optimize it? Any help will be appreciated.
Upvotes: 0
Views: 148
Reputation: 1870
Sub selects that end up being evaluated "per row of the main query" can cause tremendous performance problems once you try to scale to larger number of rows.
Sub selects can almost always be eliminated with a data model tweak.
Here's one approach: add a new is_latest
to the table to track if it's the max value (and for ties, use other fields like created time stamp or the row ID). Set it to 1 if true, else 0.
Then you can add where is_latest = 1
to your query and this will radically improve performance.
You can schedule the update to happen or add a trigger etc. if you need an automated way of keeping is_latest
up to date.
Other approaches involve 2 tables - one where you keep only the latest record and another table where you keep the history.
Upvotes: 2
Reputation: 227
Since you haven't mentioned which DB you are using, I would answer if it was for Oracle.
You can use WITH
clause to take out the subquery and make it perform just once.
WITH d AS (
SELECT max(a.date) max_date from TABLE1 a WHERE a.serialcode ='49257'
)
SELECT table2.serialcode,
p.name,
date,
power,
behind,
direction,
length,
centerlongitude,
centerlatitude,
currentlongitude,
currentlatitude
FROM table1 as table2
JOIN pivots p ON p.serialcode = table2.serial
JOIN d on (table2.date = d.max_date)
WHERE table2.serialcode = '49257'
Please note that you haven't qualified date
column, so I just assumed it belonged to table1
and not pivots
. You can change it. An advise on the same note - always qualify your columns by using table.column
format.
Upvotes: 0
Reputation: 1128
declare @maxDate datetime;
select @maxDate = max(a.date) from table1 a where a.serialcode ='49257';
SELECT table2.serialcode,
p.name,
date,
power,
behind,
direction,
length,
centerlongitude,
centerlatitude,
currentlongitude,
currentlatitude
FROM table1 as table2
JOIN pivots p ON p.serialcode = table2.serial
WHERE table2.serialcode = '49257'
and date =@maxDate;
Upvotes: 1
Reputation: 1269753
You can optimize this query using indexes. Here are somethat should help: table1(serialcode, serial, date)
, table1(serialcode, date)
, and pivots(serialcode)
.
Note: I find it very strange that you have columns called serial
and serialcode
in the same table, and the join is on serial
.
Upvotes: 0