在查询中优化WHERE子句

时间:2016-01-05 23:57:29

标签: sql

我有以下查询:

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子查询。这需要很多时间。有没有办法优化它?任何帮助将不胜感激。

4 个答案:

答案 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)

注意:我觉得很奇怪,您在同一个表中有serialserialcode列,并且联接位于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格式限定您的列。