簡體   English   中英

Java多線程可提高將數據插入數據庫的性能

[英]Java- Multi-threading to improve performance on inserting data into db

我在MYSQL的表上​​建立索引表(反向文件)。 它的工作方式是從文件中提取所有單詞,並將它們存儲到哈希集中,然后將單詞一一插入到我的數據庫表中。

它運行完美,我知道倒排文件確實需要一些時間來建立索引表。 我正在嘗試優化表索引時間,並且正在考慮使用多線程。 會提高性能嗎?

但是,我不太確定如何將其與當前程序集成,因為我是多線程的新手。

碼:

public static void main(String[] args) throws Exception {

        StopWatch stopwatch = new StopWatch();
        stopwatch.start();



        File folder = new File("D:\\PDF1");
        File[] listOfFiles = folder.listFiles();

        for (File file : listOfFiles) {
            if (file.isFile()) {
                HashSet<String> uniqueWords = new HashSet<>();
                String path = "D:\\PDF1\\" + file.getName();
                try (PDDocument document = PDDocument.load(new File(path))) {

                    if (!document.isEncrypted()) {

                        PDFTextStripper tStripper = new PDFTextStripper();
                        String pdfFileInText = tStripper.getText(document);
                        String lines[] = pdfFileInText.split("\\r?\\n");
                        for (String line : lines) {
                            String[] words = line.split(" ");

                            for (String word : words) {
                                uniqueWords.add(word)
                                ;

                            }

                        }
                        // System.out.println(uniqueWords);

                    }
                } catch (IOException e) {
                    System.err.println("Exception while trying to read pdf document - " + e);
                }
                Object[] words = uniqueWords.toArray();



                MysqlAccessIndex connection = new MysqlAccessIndex();

                for(int i = 1 ; i <= words.length - 1 ; i++ ) {

                    connection.readDataBase(path, words[i].toString());

                }

                System.out.println("Completed");

            }
        }

MySQL連接:

public class MysqlAccessIndex {
    public Connection connect = null;
    public Statement statement = null;
    public PreparedStatement preparedStatement = null;
    public ResultSet resultSet = null;

    public void connect() throws Exception {
        // This will load the MySQL driver, each DB has its own driver
        Class.forName("com.mysql.jdbc.Driver");
        // Setup the connection with the DB
        connect = DriverManager
                .getConnection("jdbc:mysql://126.32.3.20/fulltext_ltat?"
                        + "user=root&password=root");

        // Statements allow to issue SQL queries to the database
        statement = connect.createStatement();
        System.out.print("Connected");

    }
    public MysqlAccessIndex() throws Exception {

        connect();
    }


    public void readDataBase(String path,String word) throws Exception {
        try {

            // Result set get the result of the SQL query


            // This will load the MySQL driver, each DB has its own driver
            Class.forName("com.mysql.jdbc.Driver");
            // Setup the connection with the DB
            connect = DriverManager
                    .getConnection("jdbc:mysql://126.32.3.20/fulltext_ltat?"
                            + "user=root&password=root");

            // Statements allow to issue SQL queries to the database
            statement = connect.createStatement();
            System.out.print("Connected");
            // Result set get the result of the SQL query

            preparedStatement = connect
                    .prepareStatement("insert IGNORE into  fulltext_ltat.indextable values (default,?, ?) ");

            preparedStatement.setString(  1, path);
            preparedStatement.setString(2, word);
            preparedStatement.executeUpdate();
            // resultSet = statement
            //.executeQuery("select * from fulltext_ltat.index_detail");



            //  writeResultSet(resultSet);
        } catch (Exception e) {
            throw e;
        } finally {
            close();
        }

    }

我將不勝感激任何指針。

不,將數據推送到具有多個線程的數據庫通常不會加快任何速度。

相反,請嘗試以下操作:

[1]批量添加數據時,請使用數據庫引擎提供的批量添加數據原語。 我不知道mysql是否支持此功能,以及如何從Java實現。 例如,在postgres中,您將使用COPY而不是INSERT。

[2]特別是如果您不能使用COPY或類似方法,請關閉所有索引(刪除它們),然后進行所有插入,然后添加索引,這比先創建索引然后插入要快。

[3]使用事務,每隔約100次插入大約提交一次事務。 在大多數情況下,它比每次插入后提交都要快,也比幾十萬后提交要快。

[4]更早開始。 在示例代碼中,您可以立即開始插入,而不是先將所有數據填充到哈希集中,然后再添加。

[5]不要繼續做准備好的陳述; 重用同一個。

[6]您做了兩次陳述,但對此無所作為。 別; 你在浪費資源。

[7]准備陳述需要關閉。 您沒有關閉它們。 這可能會大大降低速度。 不要做太多(只有一個應該做),並在完成后關閉它們。 搜索“ ARM”,這是一個Java構造,可輕松輕松地正確關閉資源。 到現在已有10多年的歷史了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM