希格工作室

2012年4月7日 星期六

網站效能的追源溯本(Linq)

Linq真好用(廢話)

Linq搭配LinqToxxx or Entity的結合根本好用到不行

用不著寫一堆連線方案,也不用擔心SQL Injection,也不用因為寫SQL語句時,造成的一堆"字"亂七八糟的難維護,甚至連SQL都不用學了。

真是好用的東西

事不宜遲,就來寫個輸入一筆訂單,若存在符合訂單則修改數量,不存在則新增一筆,超過一筆以上則保留數量最多的並刪除其它多餘資料的標準Linq語句吧。



            var dbLink = new db();
            var catchOrder = from o in dbLink.OrderList
                             where o.OrderID == "J001"
                             select o;
            if (catchOrder.Count() == 0)
            {
                var newOrder = new OrderList();
                newOrder.OrderID = "J001";
                newOrder.OrderName = "新訂單01";
                newOrder.Quantity = 10;
                dbLink.OrderList.InsertOnSubmit(newOrder);
            }
            if (catchOrder.Count() == 1)
            {
                foreach (var upd in catchOrder)
                {
                    upd.Quantity = 11;
                }
            }
            if (catchOrder.Count() >= 2)
            {
                var MaxQuantity = catchOrder.Max(m => m.Quantity);
                var delSomeThing = from d in catchOrder
                                   where d < MaxQuantity
                                   select d;
                foreach (var delIt in catchOrder)
                {
                    dbLink.OrderList.DeleteOnSubmit(delIt);
                }
            }
            dbLink.SubmitChanges();


我們姑且不論是什麼情況會有這麼詭異的需求...那不是重點。

基本上類似這樣子的寫法應該很常見,但這語法裡有什麼問題存在?相信應該很容易知道。

Linq因為它是一個你要它做時,它才會動的東西,所以即使你在最開頭寫好了select from....,它並不會做任何事,只是放在那裡,等你找它做事,當只有在count、max....xxx等語句出現或foreach它時,才會與資料做連繫,所以在這一個簡單判斷的語法裡,總共至少需要叫資料庫做至少5~7次以上的動作,會不會太浪費資源了一點?

catchOrder.Count()catchOrder.Max()catchOrder.XXX()太好用了,又容易看懂,如果你覺得這沒什麼,結果瘋狂使用它,去試著想用的人多一點時,會發生什麼事吧?一個人是7次,1000個人就是7千次,千萬不要因為好用而濫用。

     


            var dbLink = new db();
            var catchOrder = from o in dbLink.OrderList
                             where o.OrderID == "J001"
                             select o;
            var bakOrder = catchOrder.ToList();
            int useCount = bakOrder.Count();
            if (useCount == 0)
            {
                var newOrder = new OrderList();
                newOrder.OrderID = "J001";
                newOrder.OrderName = "???01";
                newOrder.Quantity = 10;
                dbLink.OrderList.InsertOnSubmit(newOrder);
            }
            if (useCount == 1)
            {
                foreach (var upd in catchOrder)
                {
                    upd.Quantity = 11;
                }
            }
            if (useCount >= 2)
            {
                var MaxQuantity = bakOrder.Max(m => m.Quantity);
                var delSomeThing = from d in catchOrder
                                   where d < MaxQuantity
                                   select d;
                foreach (var delIt in catchOrder)
                {
                    dbLink.OrderList.DeleteOnSubmit(delIt);
                }
            }
            dbLink.SubmitChanges();

這邊做簡單的調整(但不代表最好,因為更好的有很多,這邊只是減少對資料庫溝通而已)
利用ToList先行將資料取得到記憶體中,接著計取Count保留,若有需要時亦用來計取Max,如此一來對資料庫要求的次數則從最少5~7次降為最少2次,如此便減少與資料庫之間來往,理論上而言效能應是比較好的。(實際情況請依狀況而定)

在撰寫時,最好搭配SQL Profiler瞭解你的Linq到底幹了什麼事。

2012年4月5日 星期四

網站效能的追源溯本(資料庫)

當你的網站慢了的時後,你第一時間會想什麼?

1.伺服器出問題?(IIS掛了?mem爆了?網域解析又出錯了? )
2.這支程式誰寫的?(又是xxx,快把他抓來罵)
3.大概是人太多了
4.大概是資料太多了
5.....
諸如此類的想法

如果這時候好死不死給上頭的知道了,一聲怒下,你就得開始狂查原因,翻遍所有程式,看遍所有server的設定,或狂打電話給中華電信,結果仍百思不得其解,最後上網GOOGLE,找到了許許多多網站調校的方法和建議,這當中往往都是叫你改程式,不然就再安裝新軟體,結果成本就又冒出一堆來了,只好冒死晉見老闆說要改程式(買軟體),然後被老闆白眼一頓後才核準,最後當你如願以償之後,卻發現上頭的還是跟你說一聲"喂!XXX怎麼還是那麼慢?",你可能會哭死

在你花時間改程式,加設備,搬資料,調整javascript,JPG,...,各種延遲載入,修改各介面的Response方式....諸如此類耗時費神的動作前,花個5~20分鐘重新看一下最根本的東西吧

資料庫

基本上我要講的對很多人而言是廢話,但卻又是最容易讓人遺忘的基本,資料庫是讓人塞資料用的,要塞資料一定會佔空間啊,所以你當時在建資料庫時給它多少空間?快滿時的成長空間又是多少?想想你從系統剛上線時到現在的大小差了多少?由此你就會知道你的資料存在硬碟裡到底有多散了...,越散當然越慢啊。

再來你的log檔(ldf)和資料庫檔(mdf)是不是放在同一個實體硬碟?如果是,把管資料庫的抓來痛揍一頓吧。

有無使用檔案群組(file group)功能?如果沒有,趕快用吧;如果有...麻煩看一下用到哪去了?你確定真的有正確使用?

多久沒重建你的索引了?

多久沒"完整"備份你的資料庫了?

最基本的基本...你用什麼東西當你的索引?都是varchar?甚至前面多個n? or table時不時有一堆null?別以為有些人建議varchar和char執行速度沒啥差別,null和非null也可省好多空間...當你增刪修改個N次後,你就又會知道你的資料到底又有多散了...

SQL的服務沒用到的裝了一堆?如MSSQL的Reporting Service之類的有真正用到再裝吧。

還有偶偶錄一下Profiler餵給Database Engine Tuning Advisor看看有啥要改善的吧

等到這些最基本的確定沒問題了,再去思考那些複雜的問題吧,因為資料破碎這種事,就跟燒開水一樣,你不燒它,你就沒水喝,你不燒它,你就沒電用(因為從那個放風箏被電到的人發現電以來,我們發電的方式依舊是燒開水),你不去注意破碎,你永遠被罵。

噓:回資料太多的都是廢話...除非你的DB每個都不知道多少個G...而且又同在一個instance

分享複雜的問題的參考資料:
DB:
網站效能分析操作心法-第8回-從資料庫來調校
網站效能分析操作心法-第9回-從資料庫來調校
OTHER:
快速揪出網站效能不佳的罪魁禍首

2011年12月8日 星期四

HTML5 - (Canvas 小黑人走路)

上一篇的小遊戲裡,我HTML5加上了很蠢的方塊,當作血量表,所以我就在想....一般常見的小黑人(火柴人or Matchstick Men),該怎麼寫在HTML5裡呢...?

於是這次試作了這個-小黑人走路。

過程中我發現一件事....

我空間概念有待加強~上次的3D方塊和這次的小黑人,XY都會搞的我暈頭轉向的~

還有一點就是~三角函數要重修了我~!!

我是直接把小黑人作成一個模組,所以接下來不管要他作什麼動作,應該都沒問題才是,差只差在我的空間&動作概念。