久違的更新

上個月到新公司後先開始熟悉新的環境,經過了莫約三個星期的教育訓練後才開始進入專案

新的專案使用到的技術也是之前沒有碰過的前端框架Angular,專案架構是前端與後端分離

.net 比較著重於API的開發上面,目前工作的內容以前端畫面顯示,客戶使用介面為主,跟之前公司的工作內容有滿大的差別

也趁這個機會好好的學習三大框架的其中之一,目前寫起來的感覺是Angular + TypeScript 比原生的JS還要舒服很多

與.net 相比起來 JS我比較沒有那麼的熟悉,使用Angular讓我少去許多必須在原生JS中要處理的作業,TypeScript在編譯期間可以即時反饋也讓我感到痛哭流涕

但無論如何TypeScript還是由JS而來,開發上對JS的熟悉度與掌握度越高,可以更佳的如魚得水

套用三井壽的名言

教練…….我真的好想學好JavaScript

真的要找段時間把JavaScript比較難理解的部分、DOM物件的操作弄清楚

另外新公司很有趣的一件事是

每隔週一都會有公司的創辦人為大家分享技術性的課程,從上課分享的內容以及深度和熱忱

願意在忙碌的工作中抽空與後輩分享相關的知識以及經驗,在程序員生涯位子往上晉升後,需要處理的事情與責任也就越多,面對專案的開發流程、架構的規劃、人力資源的調度、傾聽工程師的想法或是一場接一場的開發會議,手邊的雜事越多的情況下沒辦法將重心放在技術上面。

我真的很敬佩他即使到了這樣的高度仍然持續堅守在技術的第一線,也是學習的榜樣

最近公司開始有意規畫在未來的專案中引入單元測試,剛好上個月去上了資策會單元測試的進修課程,想趁還有些記憶整理一下上課所學到的東西

預計要寫一個簡單的單元測試例子,來熟悉一下為往後的專案開發做好準備,好了廢話到此


Entity Framework BulkInsert

最近在專案中遇到一個狀況是前端會去後端的API撈所有客戶的資料,以及相關的筆數,顯示相關的明細資料

測試人員的結論是有時候會沒辦法顯示總筆數,但我在本地端執行的時候一切正常,推論是環境造成的因素

但測試人員沒有辦法重現當時的狀況、第一時間也沒有相應的測試環境給我

面對這種沒辦法重現的Bug對開發人員來說是真的滿頭痛的,只能透過通靈的方式來處理

依據經驗推測是效能的問題後,開始往資料庫塞大量的假測資

using System.Diagnostics;
using Test.Models;

var db = new TestContext();

Console.WriteLine("測試資料寫入中");

var sw = new Stopwatch();
sw.Start();

for (int i = 1; i <= 5000000; i++)
{
    var Student = new Student()
    {
        Number = i,
        Name = $"Test {i}"
    };
    db.Students.Add(Student);
}

db.SaveChanges();

sw.Stop();

Console.WriteLine("測試資料寫入完畢");

Console.WriteLine($"總共花費{sw.ElapsedMilliseconds / 1000}秒");

Console.ReadLine();

一開始使用一筆一筆Add往資料庫insert

最後一次 SaveChanges

Entity Framework Bulk Insert
500萬筆資料花費約2分半的時間,當下想到一個問題,當有大量的資料需要insert進資料庫的時候有沒有更好的做法?

能花費更少的時間、更好的運用效能

SqlBulkCopy可以有效率地大量將資料批次寫入資料庫

若要在Entity Framework Bulk Insert 使用要先安裝套件

Z.EntityFramework


using System.Diagnostics;
using Test.Models;

var db = new TestContext();

Console.WriteLine("測試資料寫入中");

var sw = new Stopwatch();
sw.Start();

var StudentList = new List<Student>();

for (int i = 1; i <= 5000000; i++)
{
    var Student = new Student()
    {
        Number = i,
        Name = $"Test {i}"
    };
    StudentList.Add(Student);
}

db.BulkInsert(StudentList);

db.BulkSaveChanges();

sw.Stop();

Console.WriteLine("測試資料寫入完畢");

Console.WriteLine($"總共花費{sw.ElapsedMilliseconds / 1000}秒");

Console.ReadLine();

使用SqlBulkCopy批次的寫法同樣是500萬筆的資料時間只需要12秒

太神啦~~

相比之下SqlBulkCopy無論在效能或是時間上都有顯卓的提升,有了這次的經驗下次做大量的資料寫入都會優先考慮使用SqlBulkCopy的方法

有時間再來補Ado.net的寫法

4/4 補Ado.net

using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;

Console.WriteLine("SqlBulk批次寫入資料庫");

Stopwatch sw = new Stopwatch();

var dt = new DataTable();
dt.Columns.Add("Id", typeof(Guid));
dt.Columns.Add("Name", typeof(string));

sw.Start();

for (int i = 1; i <= 5000000; i++)
{
    var dr = dt.NewRow();
    dr["Id"] = Guid.NewGuid();
    dr["Name"] = $"Student {i}";
    dt.Rows.Add(dr);
}

string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;

using (var conn = new SqlConnection(connStr))
{
    conn.Open();

    using (var sqlBC = new SqlBulkCopy(connStr))
    {
        sqlBC.BatchSize = 100000;//設定每次批次寫入的數量
        sqlBC.BulkCopyTimeout = 60;//設置逾期秒數
        sqlBC.DestinationTableName = "dbo.Student";
        if (dt != null && dt.Rows.Count > 0)
        {
            sqlBC.WriteToServer(dt);
        }
    }
    sw.Stop();
    Console.WriteLine($"總共花費{sw.ElapsedMilliseconds / 1000}秒");
}
Visited 38 times, 1 visit(s) today

Leave A Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *