ホームページ Java &#&ベース mysql のデータ挿入が遅い理由

mysql のデータ挿入が遅い理由

Nov 01, 2020 pm 02:53 PM
mysql

mysql のデータ挿入が遅い理由: 1. メインコード、外部コード、インデックスにより挿入効率が低下する; 2. このメソッドを挿入するために for ループを使用して連続実行するため; 3. 検索結果が期限内に公開されませんでした。

mysql のデータ挿入が遅い理由

推奨: 「mysql ビデオ チュートリアル 」「java チュートリアル

最近のプロジェクトでは大量のデータをインポートする必要があり、挿入プロセスでもクエリと挿入を同時に行う必要があります。挿入されるデータ量は約100万件です。最初は100万データなんて大した量じゃないと思って、挿して挿してご飯食べて帰ってきたら、50w以上のデータを入れたら、 1秒あたり10個を挿入します。 。すごく不思議な気がするのですが、なぜ挿入すればするほどだんだん遅くなってしまうのでしょうか?そこで、挿入の時間損失を分析し始め、次の解決策を思いつきました: (INNODB エンジンは mysql で使用されています)

1. それがメインで構成されているかどうかを分析します。コード、外部コード、インデックスによる挿入効率の低下

メインコード: メインコードはテーブルごとに必要なため削除できません。 MySQL はメイン コードのインデックスを自動的に作成します。このインデックスはデフォルトでは Btree インデックスであるため、データを挿入するたびに追加の Btree を挿入する必要があります。この余分な挿入時間の複雑さは約 log(n) です。このインデックスは削除できないため、最適化できません。しかし、メインコードの制約により、挿入するたびにメインコードが出現するかどうかを確認する必要があり、そのためには log(n) が必要になります。答えは「はい」です。 プライマリ コードを自動インクリメント ID AUTO_INCREMENT に設定すると、現在の自動インクリメント値が自動的にデータベースに記録され、重複するプライマリ コードが挿入されなくなり、再現性が回避されます。プライマリコードのチェック。

外部コード: プロジェクトの挿入テーブルに外部コードが存在するため、挿入されるたびに別のテーブルで外部コードの存在を検出する必要があります。この制約はビジネス ロジックに関連しているため、気軽に削除することはできません。そして、今回のコストは他のテーブルのサイズに比例する定数である必要があり、挿入が増えても速度が遅くなることはありません。したがって除外されます。

インデックス: Btree 挿入の時間ロスを減らすために、テーブルの作成時に インデックスを作成せずに、最初にすべてのデータを挿入することができます。次に、テーブルにインデックスを追加します。この方法により、実際に時間のオーバーヘッドが削減されます。

上記のトラブルの後、再度テストしてみたところ、速度は少し速くなりましたが、500,000を超えると再び遅くなり始めました。問題の核心はここではないようです。そこで情報の確認を続けたところ、重要な問題が見つかりました:

2. 単一挿入をバッチ挿入に変更する (参考: クリックしてリンクを開きます)

JavaのexecuteUpdate(sql)メソッドはSQL操作だけを行うため、SQLで様々なリソースを呼び出す必要があり、このメソッドをforループで連続実行して挿入すると、間違いなく非常にコストがかかります。したがって、MySQL はバッチ挿入という解決策を提供します。つまり、各 SQL は直接送信されず、最初にバッチ タスク セットに保存されます。タスク セットのサイズが指定されたしきい値に達すると、これらの SQL は mysql エンドに送信されます。 100 万のデータ規模では、しきい値を 10,000 に設定します。つまり、一度に 10,000 の SQL ステートメントが送信されます。最終的な結果は非常に良好で、挿入速度は以前よりも約 20 倍速くなりました。バッチ挿入コードは次のとおりです:

public static void insertRelease() {  
        Long begin = new Date().getTime();  
        String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";  
        try {  
            conn.setAutoCommit(false);  
            PreparedStatement pst = conn.prepareStatement(sql);  
            for (int i = 1; i <= 100; i++) {  
                for (int k = 1; k <= 10000; k++) {  
                    pst.setLong(1, k * i);  
                    pst.setLong(2, k * i);  
                    pst.addBatch();  
                }  
                pst.executeBatch();  
                conn.commit();  
            }  
            pst.close();  
            conn.close();  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        Long end = new Date().getTime();  
        System.out.println("cast : " + (end - begin) / 1000 + " ms");  
    }
ログイン後にコピー

3. UPDATE ステートメントの VALUES の後には複数の (?,?,?,?)

が続きます。

# 最初、この方法は上記のものと似ていると思いましたが、他の人が行った実験を読んだ後、この方法を使用して上記のバッチ挿入を改善すると 5 倍高速になることがわかりました。後で、MySQL にエクスポートされた SQL ファイル内の挿入ステートメントもこのように書かれていることを発見しました。 。つまり、 UPDATE table_name (a1,a2) VALUES (xx,xx),(xx,xx),(xx,xx)... です。つまり、バックグラウンドで文字列を結合する必要がありますが、文字列は最後までしか挿入されないため、StringBuffer を使用すると高速に挿入できることに注意してください。コードは次のとおりです:

public static void insert() {  
        // 开时时间  
        Long begin = new Date().getTime();  
        // sql前缀  
        String prefix = "INSERT INTO tb_big_data (count, create_time, random) VALUES ";  
        try {  
            // 保存sql后缀  
            StringBuffer suffix = new StringBuffer();  
            // 设置事务为非自动提交  
            conn.setAutoCommit(false);  
            // Statement st = conn.createStatement();  
            // 比起st,pst会更好些  
            PreparedStatement pst = conn.prepareStatement("");  
            // 外层循环,总提交事务次数  
            for (int i = 1; i <= 100; i++) {  
                // 第次提交步长  
                for (int j = 1; j <= 10000; j++) {  
                    // 构建sql后缀  
                    suffix.append("(" + j * i + ", SYSDATE(), " + i * j  
                            * Math.random() + "),");  
                }  
                // 构建完整sql  
                String sql = prefix + suffix.substring(0, suffix.length() - 1);  
                // 添加执行sql  
                pst.addBatch(sql);  
                // 执行操作  
                pst.executeBatch();  
                // 提交事务  
                conn.commit();  
                // 清空上一次添加的数据  
                suffix = new StringBuffer();  
            }  
            // 头等连接  
            pst.close();  
            conn.close();  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        // 结束时间  
        Long end = new Date().getTime();  
        // 耗时  
        System.out.println("cast : " + (end - begin) / 1000 + " ms");  
    }
ログイン後にコピー


        做了以上的优化后,我发现了一个很蛋疼的问题。虽然一开始的插入速度的确快了几十倍,但是插入了50w条数据后,插入速度总是会一下突然变的非常慢。这种插入变慢是断崖式的突变,于是我冥思苦想,无意中打开了系统的资源管理器,一看发现:java占用的内存在不断飙升。 突然脑海中想到:是不是内存溢出了?

4.及时释放查询结果

        在我的数据库查询语句中,使用到了pres=con.prepareStatement(sql)来保存一个sql执行状态,使用了resultSet=pres.executeQuery来保存查询结果集。而在边查边插的过程中,我的代码一直没有把查询的结果给释放,导致其不断的占用内存空间。当我的插入执行到50w条左右时,我的内存空间占满了,于是数据库的插入开始不以内存而以磁盘为介质了,因此插入的速度就开始变得十分的低下。因此,我在每次使用完pres和resultSet后,加入了释放其空间的语句:resultSet.close(); pres.close(); 。重新进行测试,果然,内存不飙升了,插入数据到50w后速度也不降低了。原来问题的本质在这里!

以上がmysql のデータ挿入が遅い理由の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MySQL:簡単な学習のためのシンプルな概念 MySQL:簡単な学習のためのシンプルな概念 Apr 10, 2025 am 09:29 AM

MySQLは、オープンソースのリレーショナルデータベース管理システムです。 1)データベースとテーブルの作成:createdatabaseおよびcreateTableコマンドを使用します。 2)基本操作:挿入、更新、削除、選択。 3)高度な操作:参加、サブクエリ、トランザクション処理。 4)デバッグスキル:構文、データ型、およびアクセス許可を確認します。 5)最適化の提案:インデックスを使用し、選択*を避け、トランザクションを使用します。

phpmyadminを開く方法 phpmyadminを開く方法 Apr 10, 2025 pm 10:51 PM

次の手順でphpmyadminを開くことができます。1。ウェブサイトコントロールパネルにログインします。 2。phpmyadminアイコンを見つけてクリックします。 3。MySQL資格情報を入力します。 4.「ログイン」をクリックします。

MySQL:世界で最も人気のあるデータベースの紹介 MySQL:世界で最も人気のあるデータベースの紹介 Apr 12, 2025 am 12:18 AM

MySQLはオープンソースのリレーショナルデータベース管理システムであり、主にデータを迅速かつ確実に保存および取得するために使用されます。その実用的な原則には、クライアントリクエスト、クエリ解像度、クエリの実行、返品結果が含まれます。使用法の例には、テーブルの作成、データの挿入とクエリ、および参加操作などの高度な機能が含まれます。一般的なエラーには、SQL構文、データ型、およびアクセス許可、および最適化の提案には、インデックスの使用、最適化されたクエリ、およびテーブルの分割が含まれます。

なぜMySQLを使用するのですか?利点と利点 なぜMySQLを使用するのですか?利点と利点 Apr 12, 2025 am 12:17 AM

MySQLは、そのパフォーマンス、信頼性、使いやすさ、コミュニティサポートに選択されています。 1.MYSQLは、複数のデータ型と高度なクエリ操作をサポートし、効率的なデータストレージおよび検索機能を提供します。 2.クライアントサーバーアーキテクチャと複数のストレージエンジンを採用して、トランザクションとクエリの最適化をサポートします。 3.使いやすく、さまざまなオペレーティングシステムとプログラミング言語をサポートしています。 4.強力なコミュニティサポートを提供し、豊富なリソースとソリューションを提供します。

単一のスレッドレディスの使用方法 単一のスレッドレディスの使用方法 Apr 10, 2025 pm 07:12 PM

Redisは、単一のスレッドアーキテクチャを使用して、高性能、シンプルさ、一貫性を提供します。 I/Oマルチプレックス、イベントループ、ノンブロッキングI/O、共有メモリを使用して同時性を向上させますが、並行性の制限、単一の障害、および書き込み集約型のワークロードには適していません。

MySQLの場所:データベースとプログラミング MySQLの場所:データベースとプログラミング Apr 13, 2025 am 12:18 AM

データベースとプログラミングにおけるMySQLの位置は非常に重要です。これは、さまざまなアプリケーションシナリオで広く使用されているオープンソースのリレーショナルデータベース管理システムです。 1)MySQLは、効率的なデータストレージ、組織、および検索機能を提供し、Web、モバイル、およびエンタープライズレベルのシステムをサポートします。 2)クライアントサーバーアーキテクチャを使用し、複数のストレージエンジンとインデックスの最適化をサポートします。 3)基本的な使用には、テーブルの作成とデータの挿入が含まれ、高度な使用法にはマルチテーブル結合と複雑なクエリが含まれます。 4)SQL構文エラーやパフォーマンスの問題などのよくある質問は、説明コマンドとスロークエリログを介してデバッグできます。 5)パフォーマンス最適化方法には、インデックスの合理的な使用、最適化されたクエリ、およびキャッシュの使用が含まれます。ベストプラクティスには、トランザクションと準備された星の使用が含まれます

MySQLおよびSQL:開発者にとって不可欠なスキル MySQLおよびSQL:開発者にとって不可欠なスキル Apr 10, 2025 am 09:30 AM

MySQLとSQLは、開発者にとって不可欠なスキルです。 1.MYSQLはオープンソースのリレーショナルデータベース管理システムであり、SQLはデータベースの管理と操作に使用される標準言語です。 2.MYSQLは、効率的なデータストレージと検索機能を介して複数のストレージエンジンをサポートし、SQLは簡単なステートメントを通じて複雑なデータ操作を完了します。 3.使用の例には、条件によるフィルタリングやソートなどの基本的なクエリと高度なクエリが含まれます。 4.一般的なエラーには、SQLステートメントをチェックして説明コマンドを使用することで最適化できる構文エラーとパフォーマンスの問題が含まれます。 5.パフォーマンス最適化手法には、インデックスの使用、フルテーブルスキャンの回避、参加操作の最適化、コードの読み取り可能性の向上が含まれます。

SQLデータベースの構築方法 SQLデータベースの構築方法 Apr 09, 2025 pm 04:24 PM

SQLデータベースの構築には、DBMSの選択が必要です。 DBMSのインストール。データベースの作成。テーブルの作成;データの挿入;データの取得。データの更新。データの削除。ユーザーの管理。データベースのバックアップ。

See all articles