MySQL 5.6:带分组参数的复杂查询

时间:2016-07-06 11:24:59

标签: mysql sql stored-procedures

我远离MYSQL专家,而且我正在努力解决相对复杂的问题。

我有两张桌子:

包含以下列的数据表:

`Location` bigint(20) unsigned NOT NULL,
`Source` bigint(20) unsigned NOT NULL,
`Param` bigint(20) unsigned NOT NULL,
`Type` bigint(20) unsigned NOT NULL,
`InitTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`ValidTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`Value` double DEFAULT NULL

包含以下列的列表的位置组表:

`Group` bigint(20) unsigned NOT NULL,
`Location` bigint(20) unsigned NOT NULL,

数据表存储感兴趣的数据,其中每个值都是'适用于特定的有效时间'。但是,表中的数据来自定期运行的计算。运行计算的初始化时间存储在“初始化时间”中。领域。具有特定初始化时间的给定计算可能导致10个值以有效时间(A-J)输出。使用更新的初始化时间的更新近的计算可能导致以有效时间(B-K)输出另外10个值。因此,可用值存在重叠。我总是想要最新inittime的值和ValidTimes的结果集(即max(inittime))。

我可以使用以下查询确定最新的inittime:

SELECT MAX(InitTime)
FROM Data
WHERE
  Location = 100060 AND
  Source = 10 AND
  Param = 1 AND
  Type = 1;

这需要0.072秒才能执行。

但是,使用它作为子查询从Data表中检索数据会导致执行时间为45秒(这是一个非常大的表,但不是非常荒谬的)。

子查询:

SELECT Location, ValidTime, Value
FROM Data data
WHERE Source = 10
    AND Location IN (SELECT Location FROM Location Group WHERE Group = 3)
    AND InitTime = (SELECT max(data2.InitTime) FROM Data data2 WHERE data.Location = data2.Location AND data.Source = data2.Source AND data.Param = data2.Param AND data.Type = data2.Type)
ORDER BY Location, ValidTime ASC;

(为简洁起见,Snipped ValidTime限定符)

我知道可能有一些优化会对此有所帮助,但我不知道从哪里开始。相反,我创建了一个存储过程来有效地执行MAX(InitTime)查询,但由于MAX(InitTime)由Location,Source,Param和Type的组合决定,我需要传入组成特定的所有位置组。在实现必须有一种更简单的方法之前,我为此实现了基于游标的存储过程。

不考虑通过索引进行优化的问题,如何使用针对给定位置组,源,参数和类型的最新InitTime有效地对数据表执行查询?

提前致谢!

1 个答案:

答案 0 :(得分:0)

MySQL可以通过子查询(有时)优化IN。此外,索引可能会有所帮助。所以,我会把查询写成:

SELECT d.Location, d.ValidTime, d.Value
FROM Data d
WHERE d.Source = 10 AND
      EXISTS (SELECT 1 FROM LocationGroup lg WHERE d.Location = lg.Location and lg.Group = 3) AND
      d.InitTime = (SELECT max(d2.InitTime)
                    FROM Data d2
                    WHERE d.Location = d2.Location AND
                          d.Source = d2.Source AND
                          d.Param = d2.Param AND
                          d.Type = d2.Type
                   )
ORDER BY d.Location, d.ValidTime ASC;

对于此查询,您需要data(Location, Source, Param, Type, InitTime)LocationGroup(Location, Group)以及data(Source, Location, ValidTime)上的索引。