2

Java プログラムで SQL データベースを使用しようとしています。幅 7 列、行数 250 万のテーブルを作成します (次に構築する必要があるテーブルは約 2 億行になります)。2 つの問題があります。SQL テーブルの作成が遅すぎる (約 2,000 行/分) ことと、データベースの検索が遅すぎることです (可能であれば 1 秒未満で 1 億行以上を検索する必要がありますが、現在は 1 分以上かかります)。csv ファイルを作成してインポートしようとしましたが、うまくいきません

私は自分のコンピューター (i5 + 6GB RAM) で xampp と phpMyAdmin を使用しています。私がテストしているメソッドは、createTable()、writeSQL()、および searchSQL() の 3 つです。

createTable:

public static void createTable() {
    String driverName = "org.gjt.mm.mysql.Driver";
    Connection connection = null;
    try {
        Class.forName(driverName);

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    String serverName = "localhost";
    String mydatabase = "PokerRanks4";
    String url = "jdbc:mysql://" + serverName + "/" + mydatabase;                                                                        
    String username = "root";
    String password = "";

    try {
        connection = DriverManager.getConnection(url, username, password);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    ///////////////
    String table = "CREATE TABLE ranks(deckForm bigint(10) NOT NULL,rank0 int(2) NOT NULL,rank1 int(2) NOT NULL,rank2 int(2) NOT NULL,rank3 int(2) NOT NULL,rank4 int(2) NOT NULL,rank5 int(2) NOT NULL,PRIMARY KEY (deckForm),UNIQUE id (deckForm),KEY id_2 (deckForm))";
    try {
        Statement st = connection.createStatement();
        st.executeUpdate(table);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ///////////////

    try {
        connection.close();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

writeSQL():

public static void writeSQL() {
    String driverName = "org.gjt.mm.mysql.Driver";
    Connection connection = null;
    try {
        Class.forName(driverName);

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    String serverName = "localhost";
    String mydatabase = "PokerRanks4";
    String url = "jdbc:mysql://" + serverName + "/" + mydatabase;                                                                        
    String username = "root";
    String password = "";

    try {
        connection = DriverManager.getConnection(url, username, password);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    /////////////// Prepared Statement with Batch   
    PreparedStatement statement = null;
    String sql = "INSERT INTO ranks VALUES (? ,0, 0, 0, 0, 0, 0)";      
    long start = System.currentTimeMillis();
    try {
        statement = connection.prepareStatement(sql);
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                statement.setLong(1, (i*100 + j));
                statement.addBatch();
            }
            System.out.println(i);
            statement.executeBatch();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
      if (statement != null) {
        try {
          statement.close();
        } catch (SQLException e) {
        } // nothing we can do
      }
      if (connection != null) {
        try {
          connection.close();
        } catch (SQLException e) {
        } // nothing we can do
      }       
    }
    System.out.println("Total Time: " + (System.currentTimeMillis() - start) / 1000 );
    ///////////////

}

検索 SQL():

public static void searchSQL() {
    String driverName = "org.gjt.mm.mysql.Driver";
    Connection connection = null;
    try {
        Class.forName(driverName);

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    String serverName = "localhost";
    String mydatabase = "PokerRanks2";
    String url = "jdbc:mysql://" + serverName + "/" + mydatabase;                                                                        
    String username = "root";
    String password = "";

    try {
        connection = DriverManager.getConnection(url, username, password);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }



    /////////////// Option 1, Prepared Statement
    ResultSet rs = null;
    PreparedStatement pstmt = null;
    String query = "SELECT rank0, rank1, rank2, rank3, rank4, rank5 FROM ranks WHERE deckForm = ?";
    long start = System.currentTimeMillis();
    try {
        pstmt = connection.prepareStatement(query);             
        for (int i = 0; i < 100000; i++) {              
            pstmt.setLong(1, 1423354957);
            rs = pstmt.executeQuery();
            while (rs.next()) {             
                int[] arr = {rs.getInt(1), rs.getInt(2), rs.getInt(3), rs.getInt(4), rs.getInt(5), rs.getInt(6)};               
            }
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }                       
    System.out.println("Total Time: " + (System.currentTimeMillis() - start) / 1000 );
    ///////////////

    /*
    /////////////// Option 2
    Statement st = null;
    long start = System.currentTimeMillis(); 
    try {
        st = connection.createStatement();
        ResultSet rs = null;
        long deckForm = 1012213456;             
        for (int i = 0; i < 100000; i++) {          
            rs = st.executeQuery("SELECT rank0, rank1, rank2, rank3, rank4, rank5 FROM ranks WHERE deckForm = " + deckForm);
            while (rs.next()) {
                int[] arr = {rs.getInt(1), rs.getInt(2), rs.getInt(3), rs.getInt(4), rs.getInt(5), rs.getInt(6)}; 
            }
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }        
    System.out.println("Total Time: " + (System.currentTimeMillis() - start) / 1000 );
    ///////////////
    */


    try {
        connection.close();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

長くなってすみません。これを高速化するために考えられることはすべて試しましたが、わかりません。助言がありますか?

4

3 に答える 3

1

さて、あなたが行うことができるいくつかの改善があります:

  1. 検索、書き込み、または作成するたびに接続を作成するため、プールされた接続とデータソースを使用する必要があります。
  2. Explainプランを実行してクエリを最適化し、テーブルの関係とインデックスを最適化します。
  3. ストアドプロシージャを使用して呼び出すことができます。

さて、私が助けることができるのはそれだけです、確かにもっと多くのヒントがあります。

于 2013-01-28T17:15:21.463 に答える
0

挿入速度に関しては、挿入を行う前にすべてのインデックスを無効にし、完了後に再度有効にする必要があります。一括挿入速度の向上に関する多くの詳細情報については、挿入ステートメントの速度を参照してください。

クエリ速度は、おそらくCPUとディスクの速度によって制限されます。あなたは問題ではるかに多くのハードウェアを投げなければならないかもしれません。

于 2012-06-07T22:50:10.620 に答える
0

SQL テーブルの構築が遅すぎる (約 2,000 行/分)

したがって、多数の行を挿入する際の観点は確かに使用されますHeap table。これは基本的なテーブルであり、通常は単に作成された永続的なページ配列として名前が付けられてCREATE TABLEいます。検索は遅いという意味で検索には効果的ではありませんが、挿入は非常に効率的ですテーブルの最後にある最初の空き位置に行を追加するためです。しかし一方で、アイテム/行の並べ替えが保証されていないため、検索は非常に非効率的です。

データベースの検索が遅すぎる (可能であれば 1 秒以内に 1 億行以上を検索する必要がありますが、現在は 1 分以上かかります)

そのため、効率的に検索できるテーブルを作成する必要があります。を使用している場合は、物理的Oracleな実装のための多くの構造を提供しています。 最悪なことを言いたい。たとえば、MySQLがOracleのように悪い、または悪いとは言いませんが、たとえばのような物理的な実装のためのいくつかの手法を提供していませんIndex organized tablesData clusteringClustered tablesSQL ServerMySQLOracle


したがって、このアプローチについていくつかの推奨事項を言うのは非常に難しいことを意味しますが、データベースシステムの物理的な実装について真剣に考えて研究し、ステートメントを最適化するためにリレーショナル代数を見て、どのタイプのテーブルを作成する必要があるかを@duffymoが意味しましたEXPLAIN PLANE FOR最適化する結果に基づいてクエリ実行計画を説明できる権利。また、使用方法indexes、それは強力なデータベース構築ですが、各インデックスは、データベースを変更するためのより多くの操作を意味するため、インデックスなどを作成する属性について再考する必要があります.

Google を介して、データ モデリング、物理的な実装などに関する多くの有用な記事を見つけることができます。

よろしくお願いします

于 2012-06-07T23:18:30.967 に答える