日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL提高插入数据的效率(结合JDBC)

發布時間:2023/11/30 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL提高插入数据的效率(结合JDBC) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0 解決問題最佳途徑:直接找官方

先說明的是,有問題直接去找官方文檔,而不應該去百度搜索,您很容易體驗到,搜索引擎很難快速找到真正對您有價值的解決方案,而官方文檔是最快捷的途徑。

本篇也是基于官方文檔和自己的實踐得出的一些經驗,適合初學者,本人也是初學者。

測試的插入數據只有353條,但是您依然能夠體會到性能的提升。

1 【40s】使用云數據庫Mysql的體驗

下面是使用JDBC和INSERT INTO語句逐條插入信息。

/*** 將訂單信息存入表 Performance_First** @param SalesOrder 銷售提交批量訂單* @param id 當前登錄賬戶的id*/ private static void InsertSalesOrder(int id, String name, int[] SalesOrder) throws SQLException {Connection connection = null;PreparedStatement insertSalesOrder = null;String insertSalesOrderSQL = "insert into Performance_First " +"values (?,?,0,now(),?,0)";long startTime = 0;try {connection = DatabaseOperation.CreateDatabaseConnection();assert connection != null;insertSalesOrder = connection.prepareStatement(insertSalesOrderSQL);startTime = System.currentTimeMillis();// TODO 記錄時間// 插入訂單for (int TemporarySalesOrder : SalesOrder) {insertSalesOrder.setInt(1, id);insertSalesOrder.setString(2, name);insertSalesOrder.setInt(3, TemporarySalesOrder);insertSalesOrder.execute();// 應該加點插入成功的標記}} catch (Exception e) {e.printStackTrace();} finally {DatabaseOperation.CloseDatabase(connection, insertSalesOrder);}long endTime = System.currentTimeMillis();System.out.println("程序運行時間:" + (endTime - startTime) + "ms"); }

測試數據是353條,居然需要40s,我的天,難以忍受!

于是使用bing搜索半天,也沒有找到什么結果,之后看見了官方文檔,很快找到完美的解決方案

首先,進入Mysql中文文檔,找到第7章 優化(可惜沒有搜索功能……)。

我們找到INSERT語句的速度。

入一個記錄需要的時間由下列因素組成,其中的數字表示大約比例:
連接:(3)
發送查詢給服務器:(2)
分析查詢:(2)
插入記錄:(1x記錄大小)
插入索引:(1x索引)
關閉:(1)
這不考慮打開表的初始開銷,每個并發運行的查詢打開。

好了,現在明白了,使用云數據庫,連接和發送就占用了大部分時間,所以,使用本地數據庫試一試?

2 【2s】提高性能:使用本地數據庫

這部分依然使用INSERT INTO語句,速度果然提高了很多,比較不需要聯網發送數據了。

不過,我們還想再快一點,此時,你需要知道,你不知道你不知道的知識,如果官方文檔找不到蛛絲馬跡,又沒有搜索,那就只能先去搜索引擎搜一下,看看我們需要解決那個位置的問題。

不過,幸運的是,官方文檔還真有。

當從一個文本文件裝載一個表時,使用LOAD DATA INFILE。這通常比使用很多INSERT語句快20倍。參見LOAD DATA INFILE語法。

3 【20ms】進一步提高性能:使用LOAD DATA INFILE而不是INSERT INTO

我們獲取了LOAD DATA INFILE的語法原型,然后使用我們需要的部分就可以了。

3.1 使用什么選項

我們的需求是

  • 將txt文件導入到數據庫表的一部分columns
  • 將其他的columns設置為指定值
  • 根據語法原型,我們需要的語法格式是

    LOAD DATA INFILE [file_name] INTO TABLE [table_name](column1,column2,……) SET column5=expr,column6=expr……

    JDBC是這樣的(關鍵代碼)

    String sql = "LOAD DATA INFILE ? " +"INTO TABLE Performance_First(SalesOrder) " +"SET ID=?,Name=?,QueryStatus=0,SubmitTime=now(),CalculateStatus=0"; try (Connection connection = DatabaseOperation.CreateDatabaseConnection(); // 連接數據庫 ) {assert connection != null;startTime = System.currentTimeMillis();try (PreparedStatement p = connection.prepareStatement(sql);) {p.setString(1, filePath);p.setInt(2, id);p.setString(3, name);p.execute();} }

    3.2 文件路徑:客戶端與服務器

    如果指定了LOCAL,則被認為與連接的客戶端有關:
    · 如果指定了LOCAL,則文件會被客戶主機上的客戶端讀取,并被發送到服務器。文件會被給予一個完整的路徑名稱,以指定確切的位置。如果給定的是一個相對的路徑名稱,則此名稱會被理解為相對于啟動客戶端時所在的目錄。

    • 如果LOCAL沒有被指定,則文件必須位于服務器主機上,并且被服務器直接讀取。
      當在服務器主機上為文件定位時,服務器使用以下規則:
    • 如果給定了一個絕對的路徑名稱,則服務器使用此路徑名稱。
    • 如果給定了帶有一個或多個引導組件的相對路徑名稱,則服務器會搜索相對于服務器數據目錄的文件。
    • 如果給定了一個不帶引導組件的文件名稱,則服務器會在默認數據庫的數據庫目錄中尋找文件。
      注意,這些規則意味著名為./myfile.txt的文件會從服務器數據目錄中被讀取,而名為myfile.txt的同樣的文件會從默認數據庫的數據庫目錄中讀取。例如,下面的LOAD DATA語句會從db1數據庫目錄中讀取文件data.txt,因為db1是當前數據庫。即使語句明確把文件載入到db2數據庫中的表里,也會從db1目錄中讀取。
    mysql> USE db1; mysql> LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;

    注意,使用正斜杠指定Windows路徑名稱,而不是使用反斜杠。如果您使用反斜杠,您必須使用兩個。
    出于安全原因,當讀取位于服務器中的文本文件時,文件必須位于數據庫目錄中,或者是全體可讀的。另外,要對服務器文件使用LOAD DATA INFILE,您必須擁有FILE權限。

    我們選擇直接使用服務器本地的文件,而不是客戶端遠程上傳,因此不需要加LOCAL。

    此外,數據庫的文件會有默認的DATA文件夾,如果使用./則會認為是此文件夾,使用JDBC導入文件夾的時候,需要

  • 獲取java工程的路徑
  • 文件路徑 = Java工程路徑 + 文件名
  • 注意加上后綴,并且,不要使用中文

    3.3 注意

  • 不能包含中文:文件的路徑和文件名都不能包含中文
  • 您可能會遇到一些報錯,這是因為權限不足,默認情況下,只有指定文件夾中的文件可以被導入,這個問題請如果您遇到,請自行查閱資料解決。
  • 總結

    以上是生活随笔為你收集整理的MySQL提高插入数据的效率(结合JDBC)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。