1

我正在回顾我前一段时间构建和发布的应用程序。当时优化的时间不多,但我现在有一些时间来优化它。

我有一个 java DAL 类,它从数据库中加载一个包含项目的对象,如下所示:

sql = "SELECT COUNT(*) FROM projects";
count = execute(sql) // this returns the count

sql = "SELECT p.*, m.name AS clientName"
...
sql = sql + " FROM projects p"
sql = sql + " LEFT JOIN clients m ON p.clientID = m.id";

Project[] p = execute(sql, count); //this returns Project array

我遇到的问题是计数脚本需要超过 4 秒才能运行,而选择脚本需要大约 2 秒。虽然这是异步传递到表现层的,但是6秒的等待时间还是很长的(projects表只有300条左右的记录)。

我在想我可以通过添加存储过程并可能在脚本中添加额外的过滤器来改进这一点,例如“where active=1”。但我想知道是否有人可以提出更好的整体解决方案?

谢谢

编辑:我一直在用 System.nanoTime() 做一些进一步的测试,我发现计数脚本的 4 秒(3.8 秒)中最大的一块发生在执行函数中的一行中:

Connection c = getCon();

getCon 函数执行此操作:

if (con == null) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection(db_connect_string,db_userid,db_password);
}
...

所以我现在有一个新问题——为什么需要 3.8 秒才能获得 db 连接?

4

2 回答 2

2

尝试使用SELECT COUNT(1) FROM projects而不是COUNT(*). 众所周知,它可以提高一些性能。

编辑

关于您的编辑,看起来您没有使用连接池机制。如果你不使用一个,每次调用都会尝试打开一个新的连接,这可能会很昂贵。另一方面,连接池维护一个连接池,随时可以使用。如果您connection.close()在代码中执行 a ,它只会进入池以供重用,而不是完全断开连接。

您可能想要查看常用连接池的列表。我更喜欢 DBCP 或 C3P0。

注意:如果您使用 WebSphere / WebLogic / JBoss 等应用程序服务器,则无需担心这一点,因为它已经为您处理好了。您所要做的就是让您的应用程序使用DataSources 而不是直接DriverManager.getConnection()在您的应用程序服务器上配置连接。

于 2012-04-20T11:40:51.497 回答
0

确保你的表上有索引,但在更改任何代码之前,我会编写一些自动化测试来获取数字。

然后,当您进行更改时,您可以比较实际数字并查看最适合您的数字。

这样,如果您尝试存储过程,例如,您可以看到它是如何工作的。

于 2012-04-20T11:42:42.093 回答