1. 程式人生 > >關於百萬級資料轉存令人崩潰的操作

關於百萬級資料轉存令人崩潰的操作

這兩天接到一個任務,大概目標是要將現有的客戶提供的資料(Access資料庫)全部轉存到我們本地的mysql中,然後後期寫一個定期檢查原表是否更新,如果更新,則更新本地資料庫。

我一開始寫了一個小的程式碼,是利用陣列的方式,先把Aceess某一個目標表中的每一列都用list[]陣列讀出來,又N個列就newN個數組來存,然後用for迴圈,把數組裡每一列的資料寫入mysql中對應的表中的列,思路是這樣,效率不高,但是能實現,有一個目標表大概只有5000多條資料,我用這個程式碼,大概10秒鐘左右完成所有的讀和寫入操作。

具體程式碼:

string connstr = ConfigurationManager.AppSettings["connectionstring"];
            OleDbConnection conn = new OleDbConnection(connstr);
            conn.Open();
            Console.WriteLine("開啟資料庫成功");
            string sql = "select * from lwmain";
            OleDbCommand cmd = new OleDbCommand(sql, conn);
            OleDbDataReader reader = cmd.ExecuteReader();
            ArrayList listid = new ArrayList();
            ArrayList listnumberId = new ArrayList();
            ArrayList listperson = new ArrayList();
            ArrayList listlocation = new ArrayList();
            ArrayList listpartoltime = new ArrayList();
            ArrayList listnameAttrib = new ArrayList();
            ArrayList listitemname = new ArrayList();
            ArrayList listitemvalue = new ArrayList();
            ArrayList listnumber = new ArrayList();
            ArrayList listplantime = new ArrayList();
            ArrayList listequipment = new ArrayList();
            while (reader.Read())
            {
                listid.Add(reader["ID"].ToString());
                listnumberId.Add(reader["nh"].ToString());
                listperson.Add(reader["ry"].ToString());
                listlocation.Add(reader["dd"].ToString());
                listpartoltime.Add(reader["xjsj"].ToString());
                listnameAttrib.Add(reader["bhsx"].ToString());
                listitemname.Add(reader["sj"].ToString());
                listitemvalue.Add(reader["sjsz"].ToString());
                listnumber.Add(reader["bh"].ToString());
                listplantime.Add(reader["jhmc"].ToString());
                listequipment.Add(reader["sblb"].ToString());
            }
            Console.WriteLine("讀出並存儲陣列完畢。");
            conn.Close();
            string mysqlstr = ConfigurationManager.AppSettings["constr"];
            MySqlConnection mysqlconn = new MySqlConnection(mysqlstr);
            mysqlconn.Open();
            for (int i = 0; i < listid.Count; i++)
            {
                string sqlInsert = String.Format("INSERT INTO patrol_records(id,numberId,person,location,patrol_time,numAtrrib,item_name,item_value,number,plan_name,equipment)" +
                                                "VALUES "+
                                                 "({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}');", listid[i], listnumberId[i], listperson[i], listlocation[i], listpartoltime[i], listnameAttrib[i], listitemname[i], listitemvalue[i], listnumber[i], listplantime[i],listequipment[i]);
                //Console.WriteLine(sqlInsert);
                MySqlCommand cmdInsert = new MySqlCommand(sqlInsert, mysqlconn);
                cmdInsert.ExecuteNonQuery();                
            }
            Console.WriteLine("資料插入完畢");
            Console.ReadLine();
程式碼也很簡單,利用陣列先讀再寫,沒有進行優化。

但是在處理另外一個主要表,這個表的行數達到110萬餘條,如果用我這個程式碼,而且不修改的話,最少,3個小時,而且不能終端,否則就主鍵重複,可怕。Teamleader給的意見是,先介面匯入那個表的全部內容,然後更新的部分再來寫程式碼,不然效率太低,我一想也是哦,反正這些已經有的資料都是死的,Access原資料也是隻會發生Add操作而已。

基本思路就是Access->Excel->mysql

首先就是把Access資料庫裡的那張百萬級的錶轉存到excel裡面,這裡注意,傳統的Office Excel裡的單個Sheet只能存65535條資料,2007以上版本可以存到100萬多一點的量,所以注意要選07以上版本,字尾是xlsx的,不是xls。


這是匯出介面,注意,如果你勾選了第一項,匯出資料時包含格式和佈局,那麼你就算是07版本以上的office也依舊只能存65535條,遠遠不夠100萬。成功匯出到excel檔案之後,再匯入到mysql裡面。

因為本地mysql對應表的要求是所有欄位名都要改,按照公司規定的命名方式,資料型別不改,改完之後進行匯入資料,從excel裡面導。

匯入的時候,記得將excel檔案處於開啟狀態,要不然再navicat裡面是打不開excel的,在選擇了對應檔案,把欄位都一個一個對應之後就可以進行匯入了,但是,我悲劇的發現,一次還是隻能匯入65535條資料,excel檔案裡是有一百多萬條資料的,但是匯入mysql的時候,又變成了65535這個神奇的數量級。然後我就上網查,很多方法我都試過了,什麼改成csv格式 ,改成txt格式,用load import語句等等。

csv格式改完之後,原資料出現了問題,比如000000FF876F,這種型別的資料,如果是00000012314234這種不帶字元只有純數字的,那前面的0就沒了,就變成了12314234,這不符合要求,而且,在匯入的時候,就算我開著csv檔案,在navicat裡也打不開。

TXT方法,匯入之後有3好些個欄位直接亂碼,匯入倒是匯入了100多萬條,浪費我10多分鐘。

剛才在等待txt的時候,以為終於匯入成功了,終於有100多萬條了,就在匯入的等待時間來寫篇部落格吐槽一下,結果部落格還沒寫完,看了一眼亂碼資料,腦殼疼,今天完不成這個事不回家。

我目前懷疑是excel和navicat的操作位數不同,可能一個是64位一個是32位,能解釋為啥我每次直接讀excel都是65535條,明明excel裡有100多萬

2018/1/17 16:30更新

直接從Aceess裡面把表匯出成txt,用逗號分隔欄位,不再帶出成excel,然後在mysql裡找txt來匯入,注意分隔欄位符號選擇逗號,欄位對應之後開始匯入。

失敗,出現亂碼。

2018/1/17 17:20更新

匯入的時候編碼從“utf-8”改成GB2312(simplified chinese ),將mysql資料庫表和txt檔案編碼一致化

成功


上圖是mysql新增完後的,總共1199750條資料,全部寫入mysql


上圖是Access中的源資料,共1199750條,一條不差。

相關推薦

關於百萬資料令人崩潰操作

這兩天接到一個任務,大概目標是要將現有的客戶提供的資料(Access資料庫)全部轉存到我們本地的mysql中,然後後期寫一個定期檢查原表是否更新,如果更新,則更新本地資料庫。 我一開始寫了一個小的程式碼,是利用陣列的方式,先把Aceess某一個目標表中的每一列都用list[

Java 輸入一行以空格分隔字元作為輸入資料為陣列形式並輸出

用java寫一些演算法題目的時候需要輸入一些資料,像C或者CPP都可以有專用的輸入函式進行輸入,在Java裡需要稍微麻煩一些,具體程式碼如下: import java.util.Scanner; public class Main{ public static void main(

SQL Server 百萬資料提高查詢速度的方法

1.應儘量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 2.對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。 3.應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎

php - 從資料庫匯出百萬資料(CSV檔案)

將資料庫連線資訊、查詢條件、標題資訊替換為真實資料即可使用。 <?php set_time_limit(0); ini_set('memory_limit', '128M'); $fileName = date('YmdHis', time()); header('Content-

sqlserver百萬資料高效能分頁

批量插入100萬條資料 用於測試 原文地址:https://www.cnblogs.com/celine/p/9101871.html /*建立表*/ create table tb( km_h int, zkzh int, ss_h int, zw_h int ) //科目號|考生編號

百萬資料下的mysql深度解析

1.兩種查詢引擎查詢速度(myIsam 引擎 ) InnoDB 中不儲存表的具體行數,也就是說,執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行。 MyISAM只要簡單的讀出儲存好的行數即可。 注意的是,當count

Python指令碼:將Redis資料到Mysql列表中

目錄 一、思路 三、總結 一、思路        連線指定的redis和mysql資料庫,從redis中取出資料,然後存到mysql中,中間會遇到幾個問題,在下面的程式碼片段中指出 二、程式碼實現 # coding=utf-8 import js

poi實現百萬資料匯出

直接上程式碼,注意使用 SXSSFWorkbook 此類在構造表格和處理行高的時候效率極高,剛開始時我使用的 XSSFWorkbook 就出現構造表格效率極低,一萬行基本需要3秒左右,那當匯出百萬級資料就慢的要死啦,而且他會讓記憶體溢位 1.  Commen

POI匯出時寫一份到ftp伺服器,一份下載給客戶端 ftp伺服器搭建(離線安裝vsftpd),配置 poi實現百萬資料匯出 oi實現百萬資料匯出

導語:   昨天接到專案經理這麼一個需求,讓我在POI匯出Excel的時候寫一份到我之前搭建的ftp伺服器上。所以就有了這篇部落格首先我們來分析下之前的業務邏輯:我們建立並構造了一個workbook,然後構建了一個OutputStream輸出流,然後我們把資料寫入輸出流中就可以被客戶端下載。   現在我們

百萬資料多表同步

只說思路!只說思路!只說思路! 應用場景:百萬級資料多表同步 實現思路:我用的是redis的list型別,我當初的應用場景是因為平臺開始設計時候並沒有打算把所有流水記錄放在一個表中,而是一種幣種,一個流水錶。 像這種 假如說我想對所有幣種進行一個查詢、條件搜尋、修改、分頁、

Flume將 kafka 中的資料到 HDFS 中

flume1.8 kafka Channel + HDFS sink(without sources) 將 kafka 中的資料轉存到 HDFS 中, 用作離線計算, flume 已經幫我們實現了, 新增配置檔案, 直接啟動 flume-ng 即可. The Kafka channel can be

解決mongod百萬資料去重

mongodb的表結構如下 注:圖上看的眼花繚亂,這個是模擬生成環境下的資料,我不得不做了一些處理。 假定:圖中表格資料操作100萬條,以name和introduction為依據,對資料進行去重。 首先想到的是distinct,但這個是兩個欄位,不好處理。還有

PHP百萬資料匯出csv格式OR文字格式

廢話不說,先來上一個小小的DEMO <?php header('Content-Type: text/csv'); header('Content-Transfer-Encoding: binary'); for($i=0;$i<500000;$i++){ ech

如何在不停機的情況下,完成百萬資料跨表遷移?

技術團隊面臨的困難總是相似的:在業務發展到一定的時候,他們總是不得不重新設計資料模型,以此來支援更加複雜的功能。在生產環境中,這可能意味著要遷移幾百萬條活躍的資料,以及重構數以千行計的程式碼。 Stripe的使用者希望我們提供的API要具備可用性和一致性。這意味著在做遷移時,我們必須非常小心:儲存

如何在不停機的情況下,完成百萬資料跨表遷移

技術團隊面臨的困難總是相似的:在業務發展到一定的時候,他們總是不得不重新設計資料模型,以此來支援更加複雜的功能。在生產環境中,這可能意味著要遷移幾百萬條活躍的資料,以及重構數以千行計的程式碼。 Stripe的使用者希望我們提供的API要具備可用性和一致性。這意味著在做遷

微博爬蟲,每日百萬資料

Update 已經整理好的千萬級微博語料,需要的戳這裡 前言 新浪微博絕對是一個巨大的,實時的語料庫!對微博資料爬取和分析,有重大的意義。 比如,現在要調查工商銀行的服務態度,就可以抓取微博內容中包含工商銀行的微博語料,然後做情感分析,就可以得到使用者對銀

百萬資料導致查詢緩慢的問題解決方式-給SQL 新增索引

本文參考自: https://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167795.html https://www.cnblogs.com/replace/archive/2006/04/10/371067.html –原查詢語句

java實現如何將百萬資料高效的匯出到Excel表單

ps: 首先科普一下基礎知識  Excel 2003及以下的版本。一張表最大支援65536行資料,256列。也就是說excel2003完全不可能滿足百萬資料匯出的需求。  Excel 2007-2010版本。一張表最大支援1048576行,16384列;  筆者使用的是off

Access資料庫資料到MySql資料庫中

目錄 一、Navicat自帶匯入Access(*.mdb)資料的方式 二、藉助ODBC當然Access資料 1. 建立ODBC資料來源 2. 通過Navicat匯入資料 3. 新增鍵等 使用Navicat 8 for MySql來匯入資料,Access是2003版本的

oracle 海量資料插入分割槽表

某普通表T,由於前期設計不當沒有分割槽,如今幾年來的資料量已達9億+, 空間佔用大約350G,線上重定義為分割槽表不現實,故採取申請時間視窗停此表應用,改造為分割槽表。1.建立分割槽表-- Create table 建立分割槽表T_PART,分割槽從14年6月開始。creat