Heim Java JavaBase Gründe, warum MySQL Daten langsam einfügt

Gründe, warum MySQL Daten langsam einfügt

Nov 01, 2020 pm 02:53 PM
mysql

Die Gründe, warum MySQL Daten langsam einfügt: 1. Die Einfügungseffizienz wird aufgrund des Hauptcodes, des Fremdcodes und des Index verringert. 2. Aufgrund der Verwendung einer for-Schleife zum kontinuierlichen Ausführen dieser Methode zum Einfügen Abfrageergebnisse können nicht rechtzeitig veröffentlicht werden.

Gründe, warum MySQL Daten langsam einfügt

Empfohlen: „MySQL-Video-Tutorial“ „Java-Tutorial

Aktuelle Projekte erfordern den Import einer großen Datenmenge, und der Einfügevorgang erfordert auch das gleichzeitige Abfragen und Einfügen. Die eingefügte Datenmenge beträgt etwa 1 Million. Zuerst dachte ich, dass 1 Million Daten keine große Menge seien, also steckte ich ein, steckte ein und aß etwas. Als ich zurückkam, sah ich, dass ich nach dem Einfügen von mehr als 50 W Daten nur noch 10 einfügen konnte Stücke pro Sekunde. . Ich fühle mich sehr seltsam, warum wird es immer langsamer, je mehr ich es einführe? Also begann ich, den Zeitverlust beim Einfügen zu analysieren und kam auf die folgende Lösung: (INNODB-Engine, die von MySQL verwendet wird)

1 Analysieren Sie, ob die Einfügungseffizienz aufgrund des Hauptcodes, des Fremdcodes usw. verringert wird index

Hauptcode: Da der Hauptcode für jede Tabelle benötigt wird, kann er nicht gelöscht werden. MySQL erstellt automatisch einen Index für den Hauptcode. Dieser Index ist standardmäßig ein Btree-Index, sodass Sie jedes Mal, wenn Sie Daten einfügen, einen zusätzlichen Btree einfügen müssen. Bei dieser zusätzlichen Einfügezeitkomplexität geht es um log(n). Dieser Index kann nicht gelöscht und daher nicht optimiert werden. Aufgrund der Hauptcodebeschränkung muss jedoch bei jedem Einfügen überprüft werden, ob der Hauptcode angezeigt wird, was log (n) erfordert. Kann dieser Overhead reduziert werden? Die Antwort ist ja. Wir können den Hauptcode auf die Auto-Inkrement-ID AUTO_INCREMENT setzen, sodass der aktuelle Auto-Inkrement-Wert automatisch in der Datenbank aufgezeichnet wird, um sicherzustellen, dass kein doppelter Hauptcode eingefügt wird, wodurch die Duplikatprüfung des Hauptcodes vermieden wird Code. Hinweis zum äußeren Code: Da sich in der Einfügetabelle meines Projekts ein externer Code befindet, müssen Sie beim Einfügen die Existenz des äußeren Codes in einer anderen Tabelle erkennen. Diese Einschränkung hängt mit der Geschäftslogik zusammen und kann nicht einfach gelöscht werden. Und dieser Zeitaufwand sollte konstant proportional zur Größe der anderen Tabelle sein und nicht mit mehr Einfügungen langsamer werden. Also ausgeschlossen.

Index: Um den Zeitverlust beim Einfügen von Btree zu reduzieren, können wir beim Erstellen der Tabelle zuerst alle Daten einfügen, ohne einen Index zu erstellen. Anschließend fügen wir der Tabelle Indizes hinzu. Diese Methode reduziert tatsächlich den Zeitaufwand.

Nach dem oben genannten Herumwerfen und Testen stellte ich fest, dass die Geschwindigkeit etwas höher war, aber nach Erreichen von 500.000 Bar begann sie wieder langsamer zu werden. Es scheint, dass hier nicht der Kern des Problems liegt. Also habe ich die Informationen weiter überprüft und ein Hauptproblem gefunden:

2. Ändern Sie die einzelne Einfügung in eine Stapeleinfügung (Referenz: Klicken Sie, um den Link zu öffnen)

Da die Methode „executeUpdate(sql)“ in Java nur a ausführt Bei der SQL-Operation müssen Sie verschiedene Ressourcen in SQL aufrufen. Wenn Sie diese Methode zum Einfügen kontinuierlich ausführen, ist dies zweifellos sehr teuer. Daher bietet MySQL eine Lösung: Batch-Einfügung. Das heißt, jede SQL wird nicht direkt übermittelt, sondern zunächst im Batch-Task-Set gespeichert. Wenn die Größe des Task-Sets den angegebenen Schwellenwert erreicht, werden diese SQL zusammen an das MySQL-Ende gesendet. In der Datenskala von 1 Million habe ich den Schwellenwert auf 10.000 festgelegt, d. h. es werden 10.000 SQL-Anweisungen gleichzeitig übermittelt. Das Endergebnis ist ziemlich gut, die Einfügegeschwindigkeit ist etwa 20-mal schneller als zuvor. Der Batch-Einfügungscode lautet wie folgt:

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");  
    }
Nach dem Login kopieren
3. Auf die VALUES einer UPDATE-Anweisung folgen mehrere (?,?,?,?)

Ich dachte zunächst, dass diese Methode der oben genannten ähnelt , aber nachdem ich die von anderen durchgeführten Experimente studiert hatte, stellte ich fest, dass die oben beschriebene Verwendung dieser Methode zur Verbesserung der Stapeleinfügung fünfmal schneller sein kann. Später entdeckte ich, dass die Einfügeanweisungen in der von MySQL exportierten SQL-Datei ebenfalls so geschrieben waren. . Das ist UPDATE table_name (a1,a2) VALUES (xx,xx),(xx,xx),(xx,xx)... . Das heißt, wir müssen eine Zeichenfolge selbst im Hintergrund zusammenfügen. Beachten Sie, dass die Zeichenfolge mit StringBuffer schneller eingefügt werden kann, da sie nur bis zum Ende eingefügt wird. Hier ist der Code:

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");  
    }
Nach dem Login kopieren


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

4.及时释放查询结果

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

Das obige ist der detaillierte Inhalt vonGründe, warum MySQL Daten langsam einfügt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

RDS MySQL -Integration mit RedShift Zero ETL RDS MySQL -Integration mit RedShift Zero ETL Apr 08, 2025 pm 07:06 PM

Vereinfachung der Datenintegration: AmazonRDSMYSQL und Redshifts Null ETL-Integration Die effiziente Datenintegration steht im Mittelpunkt einer datengesteuerten Organisation. Herkömmliche ETL-Prozesse (Extrakt, Konvertierung, Last) sind komplex und zeitaufwändig, insbesondere bei der Integration von Datenbanken (wie AmazonRDSMysQL) in Data Warehouses (wie Rotverschiebung). AWS bietet jedoch keine ETL-Integrationslösungen, die diese Situation vollständig verändert haben und eine vereinfachte Lösung für die Datenmigration von RDSMysQL zu Rotverschiebung bietet. Dieser Artikel wird in die Integration von RDSMYSQL Null ETL mit RedShift eintauchen und erklärt, wie es funktioniert und welche Vorteile es Dateningenieuren und Entwicklern bringt.

Kann MySQL mehrere Verbindungen umgehen? Kann MySQL mehrere Verbindungen umgehen? Apr 08, 2025 pm 03:51 PM

MySQL kann mehrere gleichzeitige Verbindungen verarbeiten und Multi-Threading-/Multi-Processings verwenden, um jeder Client-Anfrage unabhängige Ausführungsumgebungen zuzuweisen, um sicherzustellen, dass sie nicht gestört werden. Die Anzahl der gleichzeitigen Verbindungen wird jedoch von Systemressourcen, MySQL -Konfiguration, Abfrageleistung, Speicher -Engine und Netzwerkumgebung beeinflusst. Die Optimierung erfordert die Berücksichtigung vieler Faktoren wie Codeebene (Schreiben effizienter SQL), Konfigurationsstufe (Anpassung von max_connections), Hardwareebene (Verbesserung der Serverkonfiguration).

MySQL, ob die Tabellenverriegelungstabelle geändert werden soll MySQL, ob die Tabellenverriegelungstabelle geändert werden soll Apr 08, 2025 pm 05:06 PM

Wenn MySQL -Modifys -Tabellenstruktur verwendet werden, werden normalerweise Metadatenverriegelungen verwendet, wodurch die Tabelle gesperrt wird. Um die Auswirkungen von Schlösser zu verringern, können die folgenden Maßnahmen ergriffen werden: 1. Halten Sie Tabellen mit Online -DDL verfügbar; 2. Führen Sie komplexe Modifikationen in Chargen durch; 3.. Arbeiten während kleiner oder absendlicher Perioden; 4. Verwenden Sie PT-OSC-Tools, um eine feinere Kontrolle zu erreichen.

Die Abfrageoptimierung in MySQL ist für die Verbesserung der Datenbankleistung von wesentlicher Bedeutung, insbesondere im Umgang mit großen Datensätzen Die Abfrageoptimierung in MySQL ist für die Verbesserung der Datenbankleistung von wesentlicher Bedeutung, insbesondere im Umgang mit großen Datensätzen Apr 08, 2025 pm 07:12 PM

1. Verwenden Sie den richtigen Index, um das Abrufen von Daten zu beschleunigen, indem die Menge der skanierten Datenmenge ausgewählt wird. Wenn Sie mehrmals eine Spalte einer Tabelle nachschlagen, erstellen Sie einen Index für diese Spalte. Wenn Sie oder Ihre App Daten aus mehreren Spalten gemäß den Kriterien benötigen, erstellen Sie einen zusammengesetzten Index 2. Vermeiden Sie aus. Auswählen * Nur die erforderlichen Spalten. Wenn Sie alle unerwünschten Spalten auswählen, konsumiert dies nur mehr Serverspeicher und veranlasst den Server bei hoher Last oder Frequenzzeiten, beispielsweise die Auswahl Ihrer Tabelle, wie beispielsweise die Spalten wie innovata und updated_at und Zeitsteuer und dann zu entfernen.

Der Hauptschlüssel von MySQL kann null sein Der Hauptschlüssel von MySQL kann null sein Apr 08, 2025 pm 03:03 PM

Der MySQL -Primärschlüssel kann nicht leer sein, da der Primärschlüssel ein Schlüsselattribut ist, das jede Zeile in der Datenbank eindeutig identifiziert. Wenn der Primärschlüssel leer sein kann, kann der Datensatz nicht eindeutig identifiziert werden, was zu Datenverwirrung führt. Wenn Sie selbstsinkrementelle Ganzzahlsspalten oder UUIDs als Primärschlüssel verwenden, sollten Sie Faktoren wie Effizienz und Raumbelegung berücksichtigen und eine geeignete Lösung auswählen.

Kann ich MySQL unter Windows 7 installieren? Kann ich MySQL unter Windows 7 installieren? Apr 08, 2025 pm 03:21 PM

Ja, MySQL kann unter Windows 7 installiert werden, und obwohl Microsoft Windows 7 nicht mehr unterstützt hat, ist MySQL dennoch kompatibel damit. Während des Installationsprozesses sollten jedoch folgende Punkte festgestellt werden: Laden Sie das MySQL -Installationsprogramm für Windows herunter. Wählen Sie die entsprechende Version von MySQL (Community oder Enterprise) aus. Wählen Sie während des Installationsprozesses das entsprechende Installationsverzeichnis und das Zeichen fest. Stellen Sie das Stammbenutzerkennwort ein und behalten Sie es ordnungsgemäß. Stellen Sie zum Testen eine Verbindung zur Datenbank her. Beachten Sie die Kompatibilitäts- und Sicherheitsprobleme unter Windows 7, und es wird empfohlen, auf ein unterstütztes Betriebssystem zu aktualisieren.

Ich kann mich nicht als Stamm bei MySQL anmelden Ich kann mich nicht als Stamm bei MySQL anmelden Apr 08, 2025 pm 04:54 PM

Die Hauptgründe, warum Sie sich bei MySQL nicht als Root anmelden können, sind Berechtigungsprobleme, Konfigurationsdateifehler, Kennwort inkonsistent, Socket -Dateiprobleme oder Firewall -Interception. Die Lösung umfasst: Überprüfen Sie, ob der Parameter Bind-Address in der Konfigurationsdatei korrekt konfiguriert ist. Überprüfen Sie, ob die Root -Benutzerberechtigungen geändert oder gelöscht und zurückgesetzt wurden. Stellen Sie sicher, dass das Passwort korrekt ist, einschließlich Fall- und Sonderzeichen. Überprüfen Sie die Einstellungen und Pfade der Socket -Dateiberechtigte. Überprüfen Sie, ob die Firewall Verbindungen zum MySQL -Server blockiert.

Kann MySQL auf Android laufen? Kann MySQL auf Android laufen? Apr 08, 2025 pm 05:03 PM

MySQL kann nicht direkt auf Android ausgeführt werden, kann jedoch indirekt mit den folgenden Methoden implementiert werden: Die Verwendung der Leichtgewichtsdatenbank SQLite, die auf dem Android -System basiert, benötigt keinen separaten Server und verfügt über eine kleine Ressourcennutzung, die für Anwendungen für Mobilgeräte sehr geeignet ist. Stellen Sie sich remote eine Verbindung zum MySQL -Server her und stellen Sie über das Netzwerk zum Lesen und Schreiben von Daten über das Netzwerk eine Verbindung zur MySQL -Datenbank auf dem Remote -Server her. Es gibt jedoch Nachteile wie starke Netzwerkabhängigkeiten, Sicherheitsprobleme und Serverkosten.

See all articles