Java和数据库显着缓慢

时间:2012-07-25 19:14:37

标签: java mysql multithreading

我有一个java程序,它为从DB读取的每个字段创建线程。我有很多领域(+10,000)。我有很慢的问题。除此之外,程序最后进入无限循环。即,有一个或多个线程永远不会结束,这使得循环无限。我尝试通过指定要读取的项目的数量(PK)来减少程序从Java代码中读取的字段数量,如下面的语句中所示:

"select hName from schema.table where 
ID between 1 AND 200";

此更改后该程序正常运行。我需要知道如何解决这个问题。包含类似(where)的条件的语句是否会影响java程序的性能?如果我没有指定订单或条件,但是我的表中有主键,那么在没有任何条件的情况下使语句更好吗?

其他类中还有一些其他插入语句。我在那里同步语句以避免两个线程具有相同的记录号。

synchronized (this) {
            Query = " insert into schema.table values (default,?,?,?)";
            Stmt = DBConnection.con.Statement(Query);
        } 

主要功能中的相关代码是:

try {
    ExecutorService threadExecutor = Executors.newFixedThreadPool(10);

    while (resultSet.next()) {
        name = resultSet.getString("hName");
        MyRunnable worker = new Myrunnable(name);
        threadExecutor.execute(worker);
        Counter++;
    }

    //This never appears
    System.out.println("End while with counter" + Counter);

    threadExecutor.shutdown();
    System.out.println("thread shutdown"); //this never appears

    // Wait until all threads are finish
    while (!threadExecutor.isTerminated()) {
        threadExecutor.awaitTermination(1, TimeUnit.SECONDS);
        System.out.println("inside the thread termination loop."); //I have infinite loop

    }

    System.out.println("Finished all threads"); //never appears

} catch (Exception e) {
    e.printStackTrace();
}

System.out.println("END MAIN");

DBConnection.con.close();

实现runnable的类在这里:

//The constructor
String threadName=null;
MyRunnable (String name)  {
    threadName=name;
}

public void run() {
    myclass Obj=new myclass();
    try {
        Obj.myFunction(name);
    } catch (Exception e) {
        System.out.println("Got an Exception: "+e.getMessage());
    }
    System.out.println(" thread exiting" + threadName);
}

2 个答案:

答案 0 :(得分:2)

  

问:我有一个java程序,可以为每个正在读取的字段创建线程   来自DB。我有很多字段(+10,000)

危险,威尔罗宾逊!

有没有人在设计阶段建议......那太疯狂了?不要那样做:)

  

问:包含类似(,where)等条件的语句是否会影响   java程序性能?

答:您是否在问“带有”where子句的SQL查询通常比整个表的天真转储执行得更好吗?“

如果是这样:是,已知“where”子句以提高查询性能:)

答案 1 :(得分:1)

不受其他事实的影响,我无法想象为什么你会出于任何原因创建10,000个线程。即使在具有数十个内核的服务器上,上下文切换也会让您失望。你的代码是如何执行的?在PC上运行的简单java程序?在服务器上?如果它在服务器上运行,您应该考虑使用应用程序服务器。然后你可以利用以下几点:首先,你可以摆脱所有线程的使用,并依靠应用服务器将请求扩展到逻辑组件(可能使用EJB3组件 - 我建议你看一下) 。其次,您可以利用连接池。创建与数据库的连接是一个昂贵的主张。如果在池中使用连接,则应用程序服务器将处理所有连接,并且仅在需要时创建新连接(请参阅Java EE文档和应用程序服务器文档以进行设置)。

最后,确保您的表上有适当的索引。例如,我假设ID已被编入索引。是这样的吗?运行解释计划,并查看正在扫描的表行数以回答查询(有关如何使用解释计划功能的说明,请参阅MySQL文档)。