【发布时间】:2012-05-01 23:53:42
【问题描述】:
我正在回顾我在一段时间前构建和发布的应用程序。当时优化的时间不多,但现在有时间稍微优化一下。
我有一个 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
我遇到的问题是 count 脚本需要超过 4 秒才能运行,而 select 脚本需要大约 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 连接?
【问题讨论】:
-
您应该使用连接池。请查看我的编辑。
-
这是一个部分答案,我应该实现连接池的 adarshr 可能是正确的,但是我设法减少了大多数数据库调用的 3.8 秒,我意识到我使用了:private Connection con;当我应该使用私有静态连接 con 时;除了第一次(这很好)之外,进行这一更改已经节省了所有数据库调用的 3.8 秒。现在我想优化 select 调用的 ~ 2 秒。任何更多的优化建议仍然很感激。
-
如果并行运行多个查询,使用静态连接会给您带来问题
-
就像@EsbenSkovPedersen 指出的那样,对此类问题使用静态变量只会使您的问题恶化。您最好的选择是使用连接池的工业级解决方案。
标签: java mysql optimization