2011-01-14 59 views
0

这是目前我的MySQL UPDATE查询,这是从用Java编写的程序中调用:优化的MySQL更新查询

String query = "UPDATE maxday SET DatePressureREL = (SELECT " + 
    "Date FROM ws3600 WHERE PressureREL = (SELECT MAX" + 
    "(PressureREL) FROM ws3600 WHERE Date >= '" + Date + 
    "') AND Date >= '" + Date + "' ORDER BY Date DESC LIMIT 1), " + 
    "PressureREL = (SELECT PressureREL FROM ws3600 WHERE " + 
    "PressureREL = (SELECT MAX(PressureREL) FROM ws3600 " + 
    "WHERE Date >= '" + Date + "') AND Date >= '" + Date + 
    "' ORDER BY Date DESC LIMIT 1), ..."; 

try { 
    s.execute(query); 
} 
catch (SQLException e) { 
    System.out.println("SQL error"); 
} 
catch(Exception e) { 
    e.printStackTrace(); 
} 

让我先解释一下,这是什么做的。我有两个表格,第一个是ws3600,它包含了列(Date,PressureREL,TemperatureOUT,露点,...)。然后我有第二个表,名为maxday,它包含DatePressureREL,PressureREL,DateTemperatureOUT,TemperatureOUT等列。现在,您可以从示例中看到,我更新每列,问题是,有没有更快的方法?我在问这个,因为我打了两次MAX,先找到该值的日期,然后找到实际值。现在我知道我可以写这样的:

SELECT Date, PressureREL FROM ws3600 WHERE PressureREL = 
    (SELECT MAX(PressureREL) FROM ws3600 WHERE Date >= '" + 
    Date + "') AND Date >= '" + Date + "' 
ORDER BY Date DESC LIMIT 1 

这样,我得到了最大,并在同一时间的最大值的日期,然后用这些值更新maxday表中的数据。但是这个解决方案的问题是,我必须执行很多查询,根据我的理解,与执行一个长mysql查询相比,需要更多的时间,因为在将每个查询发送到服务器时会有开销。

如果没有更好的办法,我应该选择哪种解决方案。第一个查询只接受一个查询,但未优化,或者第二个查询优化,但需要更多的查询,这可能意味着因为向服务器发送每个查询而导致性能增益丢失。

+0

为时已晚上周五晚上对我来说,甚至开始让我的头这一个围绕:P – 2011-01-14 21:45:00

+0

关于第二条日期,我特地到一些Serinus指出,来到一后我可能不需要这样的结论,因为我用DESC LIMIT 1限制了结果。它只是没有第二个子句而没有DESC LIMIT 1,它将返回与整个表中MAX值相等的所有值,而不仅仅是那些受参数Date限制的人。不过,我想知道我的问题真正的答案。 – 2011-01-14 22:12:38

回答

1

做2个查询对我来说不是一个真正的问题,但它们应该在事务中(读和写),这样你就可以确定你的更新值没有错。有一个查询,你没有这个问题。

我认为在读取某些数据时丢失的时间与执行写入操作所浪费的时间无关。写操作的定义并不是一件快事,你可能有触发器,你可能会从影响这个表的所有请求中清空查询缓存,数据库需要同步你在磁盘上的写入等。

对你来说更重要的是保持你的过程简单,可读和逻辑。

0

从里到外工作,它看起来像你所有的子查询做同样的事情。

使用Date> ='“+ Date +”')AND> Date'='“+ Date +”'的where子句有什么意义?

不用进入列名或技术细节,你的两个表的目的是什么? (选择MAX(PressureREL)FROM ws3600 WHERE Date> = @Date)AND日期> = @DATE ORDER BY日期DESC LIMIT 1) ,PressureREL =(SELECT PressureREL FROM ws3600 WHERE PressureREL =(SELECT MAX(PressureREL)FROM ws3600 WHERE Date> = @Date)AND Date> = @DATE ORDER BY Date DESC LIMIT 1),...“;

在此之后,理想情况下,如果你正在使用某种类型的,而不是一个字符串的SelectCommand中,你会

query.Parameters.Add(新了MySQLParameter( “@日”,yourdate));

或者,你可以做到这一点,虽然它可能让你受到SQL注入

查询= query.replace( “@日”, “ '” +日期 “'”);

无论哪种方式,它使查询更清晰。

+0

另外,这可能有助于可读性。 C#中的字符串之前的@符号将允许您在多行中包含字符串。 – Serinus 2011-01-14 21:00:23

+0

我需要两个条款检查日期,第一个条款限制选择相对压力的时间,检查日期的内部条款是在有限时间内选择MAX。 – 2011-01-14 21:18:47

1

1)我认为这个问题比SQL优化更深入。你认为这可以用不同的方式进行建模:你不需要像这样迁移数据(这很多,而且这往往太顺道)首先呢?也许只是使用FK /交叉表将两者连接在一起而不是迁移每个字段?

2)一个查询比使用JDBC来更新与新语句的连接来得更好。这是一项非常昂贵的操作(每次)。你总是希望坚持把查询集中到一个中,而不是使用迭代来执行许多语句。

0

如果您可以在一个select查询中获取所有值,则可能会有效。使用存储的过程接受一个参数(日),其作用:

一个选择语句,存储在光标的值,和

一个更新语句中,使用光标的值。

Cursor Example