首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java-多线程,用于提高向数据库中插入数据的性能

问Java-多线程,用于提高向数据库中插入数据的性能
EN

Stack Overflow用户
提问于 2018-10-26 10:46:46
回答 1查看 616关注 0票数 0

我正在MYSQL的一个表上建立一个索引表(倒排文件)。它的工作方式是从文件中提取所有单词,并将它们存储到一个哈希集,然后将这些单词逐个插入到我的数据库表中。

它工作得很好,我知道倒排文件确实需要一些时间来建立索引表。我正在尝试优化表的索引时间,并且我正在考虑使用多线程。它会提高性能吗?

然而,我不太确定如何将它与我当前的程序集成,因为我是多线程的新手。

代码:

代码语言:javascript
复制
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连接:

代码语言:javascript
复制
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();
        }

    }

如果有任何建议,我将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2018-10-26 11:10:47

不,使用多个线程将数据推送到数据库中通常不会加速任何事情。

相反,请尝试以下操作:

1当批量添加数据时,使用DB引擎提供的批量添加数据原语。我不知道mysql是否支持这一点,以及如何在java中做到这一点。例如,在postgres中,您将使用COPY而不是INSERT。

2特别是如果你不能使用复制或类似的,关闭所有的索引(删除它们),然后做所有的插入,然后添加索引,这比先创建索引再插入要快。

3使用事务,大约每100次插入提交一次事务。THis比每次插入后提交更快,而且在大多数情况下也比几十万后提交更快。

4.早点开始。在您的示例代码中,您可以立即开始插入,而不是先将所有数据填充到一个哈希集,然后再添加。

5不要一直使用准备好的语句;重复使用相同的语句。

6你写了一句话,两次,却什么也不做。不要这样做,这是在浪费资源。

7准备好的语句需要关闭。你不能闭上眼睛。这可能会大大放慢速度。不要做太多(只有一个就可以了),当你完成它的时候关闭它们。搜索“ARM”,这是一个java结构,可以方便地正确关闭资源。它现在已经有十多年的历史了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53000725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档