我有以下查询:
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');
似乎正在检索每个连接的select max子查询。这需要很多时间。有没有办法优化它?任何帮助将不胜感激。
答案 0 :(得分:2)
Sub选择最终被评估为“主查询的每一行”,一旦您尝试扩展到更大的行数,就会导致巨大的性能问题。
通过数据模型调整几乎可以消除子选择。
这是一种方法:向表中添加一个新的is_latest
以跟踪它是否为最大值(对于tie,使用其他字段,如创建的时间戳或行ID)。如果为true,则将其设置为1,否则为0.
然后,您可以在查询中添加where is_latest = 1
,这将从根本上提高效果。
如果您需要自动保持is_latest
最新状态,可以安排更新发生或添加触发器等。
其他方法涉及2个表 - 一个只保存最新记录,另一个表保存历史记录。
答案 1 :(得分:1)
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;
答案 2 :(得分:0)
您可以使用索引优化此查询。以下是一些应该有所帮助:table1(serialcode, serial, date)
,table1(serialcode, date)
和pivots(serialcode)
。
注意:我觉得很奇怪,您在同一个表中有serial
和serialcode
列,并且联接位于serial
。
答案 3 :(得分:0)
由于您还没有提到您正在使用哪个数据库,我会回答它是否适用于Oracle。
您可以使用WITH
子句取出子查询并使其仅执行一次。
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'
请注意,您没有合格的date
列,因此我认为它属于table1
而非pivots
。你可以改变它。有关同一笔记的建议 - 始终使用table.column
格式限定您的列。