The NoteBook of EricKong

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          #

          I’ve been tweaking the performance of BlogEngine.NEXT today using my favorite tool: YSlow for FireBug. One of the things YSlow checks for is the expires HTTP header for static content such as images, script files and style sheets. Since BlogEngine.NET has always used custom HTTP handlers for serving scripts and stylesheets, only the static images have been a problem.

          The problem

          The problem is that with images on hosted environments on IIS 6, it’s impossible to control the serving of them without redirecting them through an HTTP handler. That’s not a good idea for several reasons:

          • It adds unnecessary overhead by going through the ASP.NET ISAPI
          • You need to add custom code to handle the requests
          • You need to change the URL from .gif to .gif.axd or similar

          Here is what YSlow finds on my website that needs the expires header set to a far future date:


          As you can see, it is all my static images that lacks the expires header.

          The solution

          If you run IIS 6 there is no good way of adding an expires header to images unless you have control over the IIS. If your site is hosted then you probably have no control at all. If you are using IIS 7 however, you can very easily add the header in your web.config’s system.webServer section like so:

          <staticContent>
           <clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
          </staticContent>

          What happens is that all static content will now have an expires HTTP header set to the year 2020. Static content means anything that isn’t served through the ASP.NET engine such as images, script files and styles sheets. This is one of the very easy tricks that will increase the performance of your site as well as your YSlow score.

          posted @ 2010-07-21 10:23 Eric_jiang 閱讀(1176) | 評論 (0)編輯 收藏



          Div即父容器不根據內容自適應高度,我們看下面的代碼:
          <div id="main">
          <div id="content"></div>
          </div>
          當Content內容多時,即使main設置了高度100%或auto。在不同瀏覽器下還是不能完好的自動伸展。內容的高度比較高了,但容器main的高度還是不能撐開。

          我們可以通過三種方法來解決這個問題。 
          1增加一個清除浮動,讓父容器知道高度。請注意,清除浮動的容器中有一個空格。
          <div id="main">
          <div id="content"></div>
          <div style="font: 0px/0px sans-serif;clear: both;display: block"> </div>
          </div>

          2增加一個容器,在代碼中存在,但在視覺中不可見。
          <div id="main">
          <div id="content"></div>
          <div style="height:1px; margin-top:-1px;clear: both;overflow:hidden;"></div>
          </div>

          3增加一個BR并設置樣式為clear:both。
          <div id="main">
          <div id="content"></div>
          <br style="clear:both;" />
          </div>

          補充:
          <div id="main">
          <div id="content">
            <p>demo1</p>
            <p>demo2</p>
            <p>demo3</p>
          </div>
          </div>
          #main { border:1px solid #999999; background-color:#CCCCCC; height:100%; overflow:hidden;}
          #content { float:left;}

          以上三個方法都不是最好的解決方法,因為在程序代碼觀念中是提倡盡量不要添加無意義的標簽代碼

          介紹我的解決方法是直接在最外層div加以下樣式
          #main {
          height:100%;
          overflow:hidden;
          }
          posted @ 2010-07-20 10:14 Eric_jiang 閱讀(438) | 評論 (1)編輯 收藏

               摘要: 1、頁面代碼 Html代碼 <%@ page contentType="text/html;charset=UTF-8"%>   <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> ...  閱讀全文
          posted @ 2010-07-14 21:26 Eric_jiang 閱讀(1793) | 評論 (0)編輯 收藏

          1. import java.awt.AlphaComposite;      
          2. import java.awt.Color;      
          3. import java.awt.Font;      
          4. import java.awt.Graphics2D;      
          5. import java.awt.Image;      
          6. import java.awt.geom.AffineTransform;      
          7. import java.awt.image.AffineTransformOp;      
          8. import java.awt.image.BufferedImage;      
          9. import java.io.File;      
          10. import java.io.IOException;      
          11.      
          12. import javax.imageio.ImageIO;      
          13.      
          14.      
          15. public final class ImageUtils {      
          16.     /**    
          17.      * 圖片水印    
          18.      *     
          19.      * @param pressImg    
          20.      *            水印圖片    
          21.      * @param targetImg    
          22.      *            目標圖片    
          23.      * @param x    
          24.      *            修正值 默認在中 間    
          25.      * @param y    
          26.      *            修正值 默認在中 間    
          27.      * @param alpha    
          28.      *            透明度    
          29.      */     
          30.     public final static void pressImage(String pressImg, String targetImg, int x, int y, float alpha) {      
          31.         try {      
          32.             File img = new File(targetImg);      
          33.             Image src = ImageIO.read(img);      
          34.             int wideth = src.getWidth(null);      
          35.             int height = src.getHeight(null);      
          36.             BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);      
          37.             Graphics2D g = image.createGraphics();      
          38.             g.drawImage(src, 0, 0, wideth, height, null);      
          39.             // 水印 文件      
          40.             Image src_biao = ImageIO.read(new File(pressImg));      
          41.             int wideth_biao = src_biao.getWidth(null);      
          42.             int height_biao = src_biao.getHeight(null);      
          43.             g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));      
          44.             g.drawImage(src_biao, (wideth - wideth_biao) / 2, (height - height_biao) / 2, wideth_biao, height_biao, null);      
          45.             // 水印 文件結束      
          46.             g.dispose();      
          47.             ImageIO.write((BufferedImage) image, "jpg", img);      
          48.         } catch (Exception e) {      
          49.             e.printStackTrace();      
          50.         }      
          51.     }      
          52.      
          53.     /**    
          54.      * 文字水印    
          55.      *     
          56.      * @param pressText    
          57.      *            水印文字    
          58.      * @param targetImg    
          59.      *            目標圖片    
          60.      * @param fontName    
          61.      *            字體名稱    
          62.      * @param fontStyle    
          63.      *            字體樣式    
          64.      * @param color    
          65.      *            字體顏色    
          66.      * @param fontSize    
          67.      *            字體大小    
          68.      * @param x    
          69.      *            修正值    
          70.      * @param y    
          71.      *            修正值    
          72.      * @param alpha    
          73.      *            透明度    
          74.      */     
          75.     public static void pressText(String pressText, String targetImg, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha) {      
          76.         try {      
          77.             File img = new File(targetImg);      
          78.             Image src = ImageIO.read(img);      
          79.             int width = src.getWidth(null);      
          80.             int height = src.getHeight(null);      
          81.             BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);      
          82.             Graphics2D g = image.createGraphics();      
          83.             g.drawImage(src, 0, 0, width, height, null);      
          84.             g.setColor(color);      
          85.             g.setFont(new Font(fontName, fontStyle, fontSize));      
          86.             g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));      
          87.             g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y);      
          88.             g.dispose();      
          89.             ImageIO.write((BufferedImage) image, "jpg", img);      
          90.         } catch (Exception e) {      
          91.             e.printStackTrace();      
          92.         }      
          93.     }      
          94.      
          95.     /**    
          96.      * 縮放    
          97.      *     
          98.      * @param filePath    
          99.      *            圖片路徑    
          100.      * @param height    
          101.      *            高度    
          102.      * @param width    
          103.      *            寬度    
          104.      * @param bb    
          105.      *            比例不對時是 否需要補白    
          106.      */     
          107.     public static void resize(String filePath, int height, int width, boolean bb) {      
          108.         try {      
          109.             double ratio = 0; // 縮放比例      
          110.             File f = new File(filePath);      
          111.             BufferedImage bi = ImageIO.read(f);      
          112.             Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);      
          113.             // 計算 比例      
          114.             if ((bi.getHeight() > height) || (bi.getWidth() > width)) {      
          115.                 if (bi.getHeight() > bi.getWidth()) {      
          116.                     ratio = (new Integer(height)).doubleValue() / bi.getHeight();      
          117.                 } else {      
          118.                     ratio = (new Integer(width)).doubleValue() / bi.getWidth();      
          119.                 }      
          120.                 AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);      
          121.                 itemp = op.filter(bi, null);      
          122.             }      
          123.             if (bb) {      
          124.                 BufferedImage image = new BufferedImage(width, height,      
          125.                         BufferedImage.TYPE_INT_RGB);      
          126.                 Graphics2D g = image.createGraphics();      
          127.                 g.setColor(Color.white);      
          128.                 g.fillRect(0, 0, width, height);      
          129.                 if (width == itemp.getWidth(null))      
          130.                     g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);      
          131.                 else     
          132.                     g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null);      
          133.                 g.dispose();      
          134.                 itemp = image;      
          135.             }      
          136.             ImageIO.write((BufferedImage) itemp, "jpg", f);      
          137.         } catch (IOException e) {      
          138.             e.printStackTrace();      
          139.         }      
          140.     }      
          141.      
          142.     public static void main(String[] args) throws IOException {      
          143.         pressImage("G:""imgtest""sy.jpg", "G:""imgtest""testjpg", 0, 0, 5f);      
          144.         pressText("我是 文字水印", "G:""imgtest""testjpg", "黑體", 36, Color.white, 80,      
          145.                 0, 0, 3f);      
          146.         resize("G:""imgtest""testjpg", 500, 500, true);      
          147.     }      
          148.      
          149.     public static int getLength(String text) {      
          150.         int length = 0;      
          151.         for (int i = 0; i < text.length(); i++) {      
          152.             if (new String(text.charAt(i) + "").getBytes().length > 1) {      
          153.                 length += 2;      
          154.             } else {      
          155.                 length += 1;      
          156.             }      
          157.         }      
          158.         return length / 2;      
          159.     }      
          160. }     
          161.  
          posted @ 2010-07-14 20:04 Eric_jiang 閱讀(281) | 評論 (0)編輯 收藏

          很早之前就聽說有jslint這個東東,但是一直沒有用過。說得簡單點,這是一個js代碼校驗的工具。

          官方網站:http://www.jslint.com/lint.html

          在線校驗地址:http://www.jslint.com/

          用在線校驗的校驗有些不太方便,因為每次都要粘貼復制代碼。如果能把jslint結合到EditPlus里面應該灰常方便。

          找到如下解決方案

          http://www.jslint.com/fulljslint.js下載這個js文件,放到editplus的安裝目錄中,我的是C:"Program Files"EditPlus 3

          菜單文本:javascript調試
          調試命令:cmd /c
          參數:cscript “$(FileName)” cscript “jslint的路徑” < "$(FileName)"(被刪除的部分是網上大部分的說法,但是我實際操作了一下,發現這段命令只會檢測jslint這個文件,于是我嘗試刪除了<前面的東東,發現就能校驗當前文件了)
          初始目錄:$(FileDir)
          鉤選:捕捉輸出
          在輸出模式使用正則表達式:^Lint at line ([0-9]+) character ([0-9]+).*$”
          上面這行好像就是默認的,不用改。


          EditPlus里面配置jslint

          存在問題:目前校驗下來,一般的js代碼如果有問題,會正常報錯。但是對于我們的框架而言,只要檢測到$符號,就會報錯。
          我想這個應該在jslint.js文件中處理一下對應的邏輯。

          posted @ 2010-07-14 15:52 Eric_jiang 閱讀(1011) | 評論 (0)編輯 收藏

          win7比以往任何一個操作系統占用內存多,系統啟動的時候自帶了很多系統服務,但多數系統服務我們是用不上的,完全可以關閉這些服務來節省系統資源,下面列出win7下可以關閉的系統服務,大家可以根據的實際使用情況來選擇關閉哪些不用的服務。

          Adaptive brightness
          監視周圍的光線狀況來調節屏幕明暗,普通用戶沒有觸摸屏類的顯示,該功能就可以放心禁用。
          Application Layer Gateway Service
          Windows XP/Vista中也有該服務,作用也差不多,是系統自帶防火墻和開啟ICS共享上網的依賴服務,如果裝有第三方防火墻且不需要用ICS方式共享上網,完全可以禁用掉。
          Application Management
          該服務默認的運行方式為手動,該功能主要適用于大型企業環境下的集中管理,因此家庭用戶可以放心禁用該服務。
          Background Intelligent Transfer Service
          在后臺傳輸客戶端和服務器之間的數據。如果禁用了BITS,一些功能,如 Windows Update,就無法正常運行。該服務的默認運行方式是自動,這個服務的主要用途還是用于進行Windows Update或者自動更新,最好不要更改這個服務。
          Base Filtering Engine
          同樣為系統防火墻,VPN以及IPsec提供依賴服務,同時也是系統安全方面的服務,如果使用第三方VPN撥號軟件并且不用系統的防火墻以及ICS共享上網,為了系統資源,關閉它吧,否則就別動它。
          BitLocker Drive Encryption Service
          向用戶接口提供BitLocker客戶端服務并且自動對數據卷解鎖。該服務的默認運行方式是手動,如果你沒有使用BitLocker設備,該功能就可以放心禁用。
          Block Level Backup Engine Service
          估計是和備份恢復方面用的服務,無任何依賴關系,默認是手動,也從來沒有看他啟動過。就放那吧,不用管了。
          Bluetooth Support Service
          如果你沒有使用藍牙設備,該功能就可以放心禁用。
          Certificate Propagation
          為智能卡提供證書。該服務的默認運行方式是手動。如果你沒有使用智能卡,那么可以放心禁用該服務。
          CNG Key Isolation
          那么這個服務將被使用,建議不使用自動有線網絡配置和無線網絡的可以關掉。
          Computer Browser
          不過如果你沒有使用局域網或者你根本就不想使用局域網,該功能就可以放心禁用,禁用后任然可以使用
          Diagnostic Policy Service
          Diagnostic Policy服務為Windows組件提供診斷支持。如果該服務停止了,系統診斷工具將無法正常運行。如果該服務被禁用了,那么任何依賴該服務的其他服務都將無法正常運行。該服務的默認運行方式是自動,Vista或IE7有時會彈出對話框問你是否需要讓它幫忙找到故障的原因,只有1%的情況下它會幫忙修復Internet斷線的問題,可以關掉。
          Diagnostic Service Host
          這就是幫上面Diagnostic Policy Service做具體事情的服務,會隨著上面的服務啟動,可以一起關掉。
          Diagnostic System Host
          基本和Diagnostic Policy Service/Diagnostic Service Host是同類,可以一起關掉。
          Distributed Link Tracking Client:
          這個功能一般都用不上,完全可以放心禁用。

          Distributed Transaction Coordinator
          很多應用以及SQL,Exchange Biztalk等服務器軟件都依賴這個服務,可以不啟動它,但不要Disabled 它。
          Extensible Authentication Protocol
          不用802.1x認證、無線網絡或VPN 可以不啟動它,不要Disabled 它。
          Fax
          利用計算機或網絡上的可用傳真資源發送和接收傳真。不用我說了吧,很明顯就能看出來是和傳真有關的。手動或禁用
          Function Discovery Provider Host
          功能發現提供程序的主機進程。PnP-X和SSDP相關,如果無相關設備就關了吧。
          Function Discovery Resource Publication
          PnP-X和SSDP相關,如果無相關設備就關了吧。
          HomeGroup Listener
          為家庭群組提供接收服務,該服務的默認運行方式是手動,如果你不使用家庭群組來共享圖片視頻及文檔,那么該服務可以禁用。
          HomeGroup Provider
          為家庭群組提供網絡服務,該服務的默認運行方式是自動,如果你不使用家庭群組來共享圖片視頻及文檔,那么該服務可以禁用。
          Human Interface Device Access
          如果你不想你機器或筆記本鍵盤上面的那些特別的附加按鍵起作用、不用游戲手柄之類可以關掉這個服務。
          IKE and AuthIP IPsec Keying Modules
          不用VPN或用第三方VPN撥號的話可以禁用。
          Internet Connection Sharing (ICS)
          如果你不打算讓這臺計算機充當ICS主機,那么該服務可以禁用,否則需要啟用。
          IP Helper
          說白了就是讓IPv4和IPv6相互兼容,現在的情況下不是特別需要,其實設置成Disabled 也無妨。
          IPsec Policy Agent
          某些公司的網絡環境要求必須打開,它提供一個TCP/IP網絡上客戶端和服務器之間端到端的安全連接。其他的情況建議設置成禁用。
          KtmRm for Distributed Transaction Coordinator
          對開發人員來說是比較有用,對于一般的用戶或者非開發人員來說,設置成手動。
          Link-Layer Topology Discovery Mapper
          應該是支持LLTD (Link Layer Topology Discovery) 技術,可以精確地顯示支持LLTD的設備在網絡結構中的位置,比如Vista的無線地圖 ,保持默認手動。
          Microsoft iSCSI Initiator Service
          如果本機沒有iSCSI設備也不需要連接和訪問遠程iSCSI設備,設置成禁用。
          Microsoft Software Shadow Copy Provider
          卷影拷貝,如果不需要就可以設為禁用。
          Net.Tcp 端口共享服務
          一般用戶和非開發人員,還是Disabled就行了。
          Netlogon
          登陸域會用到它。工作組環境可以設為禁用。
          Offline Files
          脫機文件服務,使用這個功能系統會將網絡上的共享內容在本地進行緩存,可以關掉。
          Parental Controls
          父母控制服務,用于IE上網設置里的,如果是自己用電腦,就關掉它。
          Peer Name Resolution Protocol/ Peer Networking Grouping / Peer Networking Identity Manager
          如果你不嘗試WCF的P2P功能或開發,那么連同相關的兩個服務都可以關掉。
          PnP-X IP Bus Enumerator
          目前還用不上,關了它!
          PNRP Machine Name Publication Service
          一般不需要它。默認即可。
          Portable Device Enumerator Service
          用來讓Windows Media Player和移動媒體播放器比如MP3進行數據和時鐘同步。如不需要同步建議關閉。
          Print Spooler
          將文件加載到內存供稍后打印。打印服務,不用多說了,有(包括虛擬的)就開,沒有就關。
          Problem Reports and Solutions Control Panel Support
          開了它基本也解決不了你計算機出的問題。禁用吧。
          Program Compatibility Assistant Service
          如果你使用到Program Compatibility Assistant或者需要將你的程序設置成兼容模式運行,比如運行在Win98 或 Windows 2000的方式下,就修改成自動,強烈建議設置為自動,如果沒有這樣的程序,就關掉它。
          Quality Windows Audio Video Experience
          個人感覺這個不起什么作用,支持這樣技術的網絡服務也不多。還是系統資源比較重要,關了它。
          Remote Desktop Configuration/ Remote Desktop Services/ Remote Desktop Services UserMode Port Redirector
          系統自帶的遠程桌面服務,如果不用它,就連同和它相關的兩個服務一起關掉
          Remote Registry
          家庭個人用戶最好禁用此服務,公司管理就需要打開了。
          Routing and Remote Access
          在局域網以及廣域網環境中為企業提供路由服務。提供路由服務的。不用就關。
          Secondary Logon
          允許一臺機器同時有兩個用戶登錄,個人應用基本不需要。
          Security Center
          監視系統安全設置和配置。不想聽它提示,就關上它。

          Server
          如果不需要在網絡上共享什么東西就可以關掉。
          Shell
          Hardware Detection
          如果你不喜歡自動播放功能,那么設置成手動或禁用,這樣你新插入一個U盤,可能系統沒有任何提示。
          Smart Card/ Smart Card Removal Policy
          如果你沒有使用Smart Card,建議設置成禁用。
          SNMP Trap
          允許你的機器處理簡單網絡管理協議,很多網管協議是基于SNMP的。不是網管的話建議關閉。
          SSDP Discovery
          搜索使用了SSDP發現協議的一些設備,比如一些非即插即用的設備,如果沒有相關設備,可以關了它。
          Tablet PC Input Service
          啟用 Tablet PC 筆和墨跡功能,非Table PC及不使用手寫板就可以關掉它。
          TCP/IP NetBIOS Helper
          使得你可以在計算機之間進行文件和打印機共享、網絡登錄。不需要可關閉。
          Telephony
          Adsl撥號就要用到這個服務,如果是路由器上網,就可以關了它。
          Thread Ordering Server
          提供特別的線程排序和調度服務,如果用不上,可以設置成手動,但不建議設置成自動。
          TPM Base Services
          可以設置成手動,如果你沒有使用帶TPM模塊的計算機,可以禁用掉。
          Virtual Disk
          提供用于磁盤、卷、文件系統和存儲陣列的管理服務。提供存儲設備軟件卷和硬件卷的管理,不要將其設置成禁用 。
          WebClient
          簡單的說如果你不需要Web目錄或類似功能,就可以關掉它。
          Windows Backup
          提供 Windows 備份和還原功能。Windows備份和版本恢復功能,一直都不好使,可以關掉。
          Windows Biometric Service
          如果你沒有使用生物識別設備,如指紋識別系統,該功能就可以放心禁用,否則保持默認。
          Windows CardSpace
          像Smart Card一樣的個人標識管理,.NET Framework 3.0提供的一個WCF編程模型。一般用戶可以關閉。
          Windows Connect Now - Config Registrar
          無線網絡要用的東西,如果沒有,就關上它。
          Windows Defender
          可以加強安全,防范木馬和一些惡意程序,最主要的是免費。不需要可以關閉。
          Windows Error Reporting Service
          沒人喜歡錯誤,對你和微軟而言,錯誤報告傳送過去都沒什么用。關了它。
          Windows Firewall
          Windows 防火墻不用多說什么了。如果不需要就禁用。
          Windows Image Acquisition (WIA)
          專門為掃描儀和數碼相機等提供圖像捕獲和獲取功能。有就開著,沒有就關。
          Windows Media Center Service Launcher/ Windows Media Center Receiver Service / Windows Media Center Scheduler Service
          通過網絡為Windows Media Extender(像XBox)等傳送多媒體文件,建議禁止,除非你需要這個功能。
          Windows Modules Installer
          如果你不使用Windows Updates,那么可以禁止這個服務。
          Windows Time
          和服務器同步時間的,一般我都關閉它。
          Windows Update
          這個功能取決于你了,它和Background Intelligent Transfer Service、Modules Installer服務關聯。
          WinHTTP Web Proxy Auto-Discovery Service
          該服務使應用程序支持WPAD協議的應用,因為大多數的情況下不會用到。建議關閉。
          Wired AutoConfig
          此服務對以太網接口執行 IEEE 802.1X 身份驗證。其實很多的時候,還是要自己設置的。默認即可。
          WLAN AutoConfig
          不用無線網絡可以關掉
          posted @ 2010-07-13 22:17 Eric_jiang 閱讀(1740) | 評論 (0)編輯 收藏

          當 需要分析某個查詢的效能時,最好的方式之一查看這個查詢的執行計劃。執行計劃描述SQL Server查 詢優化器如何實際運行(或者將會如何運行)一 個特定的查詢。

          查 看查詢的執行計劃有幾種不同的方式。它們包括:

          SQL Server查詢分析器里有一個叫做顯示實際執行計劃的選項(位于查詢下拉菜單中)。如果打開了這個選項,那么 無論何時在查詢分析器中運行一個查詢,都會得到一個顯示在單獨窗口的查詢執行計劃(以圖形的格式)

          如果只是想看下執行計劃而不想 運行查詢,那么可以選擇顯示預估的執行計劃選項(位于查詢下拉菜單中)。當選擇這個選項后,執行計 劃會馬上顯示出來(以圖形的格式)。兩者的不同之處在于當實際運行一個查詢時,當前的服務器上的運算也會被考慮進去。大多數情況下,兩種方 式產生的執行計劃產生的結果是相似的。

          當建立一個SQL Server Profiler追蹤時,可以收集的一個事件是MISC: Execution Plan.這個信息(以文本的形式)顯示查詢優化器用來執行查詢 的計行計劃。

          可以在查詢分析器上執行SET SHOWPLAN_TEXT ON命令。這條命令被執行后,所有在當前這個查詢分析器會話中執行的查詢都不會運行,而是會顯示一個基于文本的 執行計劃。執行某條用到臨時表的查詢時,必須在執行查詢先運行SET STATISTICS PROFILE ON語句。

          上面這些選項中,我更喜歡使用顯示實際執行計劃這個選項。它以圖形的方式輸 出信息,并且考慮到了當前服務器上的那些運算。[7.0, 2000] Updated 8-5-2005

          *****

          如果在執行計劃中看到如下所示 的任何一項,就應該將它們視作警告信號并調查它們以找出潛在的性能問題。從性能方面來說,下面所示的每一項都是不理想的。

          Index or table scans(索引或者表掃描)可能意味著需要更好的或者額外 的索引。

          Bookmark Lookups(書簽查找)考慮修改當前的聚集索引,使用復蓋索引,限制SELECT語句中的字段數量。

          Filter(過濾)WHERE從句中移除用到的任何函數, 不要在SQL語句中包含視圖,可能需要額外的索引。

          Sort(排序)數據是否真的需要排序?可否 使用索引來避免排序?在客戶端排序是否會更加有效率?

          無一例外地避免這些操作是不可 能的,但是避免得越多,查詢性能就會越快。[7.0,2000,2005]

          *****

          如果有在存儲過程中或者其它T-SQL批處理代碼中用到了臨時表, 就不能在查詢分析器或Management Studio使用顯示預估的執行計劃選項來評估查詢。必須實際運 行這個存儲過程或者批處理代碼。這是因為使用顯示預估的執行計劃選項來運行一個查詢時,它并沒有實際被運行,臨時表也沒有創建。由于臨時表沒 有被創建,參考到臨時表的代碼就會失敗,導致預估的執行計劃不能成創建成功。

          從另一方面來說,如果使用的是 表變量而不是臨時表,則可以使用顯示預估的執行計劃選項。[7.0,2000,2005] Updated 8-5-2005

          *****

           

          如果在查詢分析器或Management Studio中對一個非常復雜的查詢的執行計劃進行分析,可能會覺得它的執行計劃既難于看懂也難于分析。那么,按照查詢的邏輯將它拆分成幾 個部分,然后分別對這些部分進行分析會容易得多。[7.0,2000,2005] Updated 8-5-2005

          *****

           

          圖形執行計劃并不總是容易讀懂 和解釋。查看執行計劃時記住如下幾點:

          非常復雜的執行計劃會被分成多 個部分,它們分別列出在屏幕上。每個部分分別代表查詢優化器為了得到最終結果而必須執行的單個處理或步驟。

          執行計劃的每個步驟經常會被拆 分成一個個更小的子步驟。不幸的是,它們是從右至左顯示在屏幕上的。這意味著你必須滾動到圖形執行計劃的最右邊去查看每個步驟是從哪兒開始的。

          每個步驟與子步驟間通過箭頭連 接,藉此顯示查詢執行的路徑。

          最后,查詢的所有部分在屏幕頂 部的左邊匯總到一起。

          如果將鼠標移動到任何執行計劃 任何步驟或者子步驟的上面,就會顯示一個彈出式窗口,上面顯示該步驟或子步驟的更加詳細的信息。

          如果將鼠標移動到連接步驟或子 步驟的箭頭上,就可以看到一個彈出式窗口,上面顯示有多少筆記錄從一個步驟或子步驟移動到另一個步驟或子步驟。

          [7.0, 2000, 2005] Updated 8-5-2005

           

           

          圖形執行計劃上連接每個圖標的箭頭粗細不同。箭頭的粗細表示每個圖標之間移動的數據行數量以及數據行大小移動所需的相對成本。箭頭越粗,相對成本就越高。

           

          可以使用這個指示器來快速測量一個查詢。你可能會特別關注粗箭頭以了解它如何影響到查詢的效能。例如,粗線頭應該在圖形執行計 劃的右邊,而非左邊。如果看到它們在左邊,就意味著太多的數據行被返回,這個執行計劃也不是最佳的執行計劃。[7.0,2000,2005]

          *****

           

          執行計劃的每個部分都被分配了一個成本百分比。它表示這個部分耗用了整個執行計劃的多少資源。當對一個執行計劃進行分析的時候,應該將精力集中于有著高成本百分比的那些部 分。這樣就可以在有限的時間里找到可能性最大的問題,從而回報了你在時間上的投資。[7.0, 2000, 2005]

          *****

           你可能會注意到一個執行計劃的某些部分被執行了不止一次。作為執行計劃分析的一部分,應該將你的一些時間集中在任何執行了超過一次的那些部分上,看看是否有什么方式減少它們執行的次 數。執行的次數越少,查詢的速度就越快。[7.0, 2000, 2005]

          *****

           在執行計劃中你可以看到I/OCPU成本。它們沒有實際的意義,例如代 表特定資源的使用量。查詢優化器使用這些數字來做出最佳選擇。它們可用來參考的一個意義是,較小的I/OCPU成本比較大的I/OCPU成本使用更少的服務器資源。[7.0, 2000, 2005]

          *****

           

          查看SQL Server圖形執行計劃時,可以查找的非常有 用的一個東西就是查詢優化器如何為給定的查詢使用索引來從表中獲取數據。通過查看是否有用到索引,以及索引如何被使用,都有助于判斷當前的索引是否使得查詢執行得盡可能的快。

          將鼠標移到圖形執行計劃上的表名(以及它的圖標)上面,就會彈出一個窗口,從它上面可以看到一些信息。這些信息讓你知道是否有用到索引來從表中獲取數據,以及它是如何使用的。 這些信息包括:

          ·     Table Scan(表掃描):如果看到這個信息,就說明數據表上沒有聚 集索引,或者查詢優化器沒有使用索引來查找。意即資料表的每一行都被檢查到。如果資料表相對較小的話,表掃描可以非常快速,有時甚至快過使用索引。

          因此,當看到有執行表掃描時,第一件要做的事就是看看數據表有多少數據行。如果 不是太多的話,那么表掃描可能提供了最好的總體效能。但如果數據表大的話,表掃描就極可能需要長時間來完成,查詢效能就大受影響。在這種情況下,就需要仔 細研究,為數據表增加一個適當的索引用于這個查詢。

          假設你發現某查詢使用了表掃描,有一個合適的非聚集索引,但它沒有用到。這意味 著什么呢?為什么這個索引沒有用到呢?如果需要獲得的數據量相對數據表大小來說非常大,或者數據選擇性不高(意味著同一個字段中重復的值很多),表掃描經常會比索引掃描快。例如,如果一個數據表有10000個數據行,查詢返回1000行,如果這個表沒有聚集索引的話,那么表掃描將比使用一個非聚集索引 更快。或者如果數據表有10000個數據行,且同一 個字段(WHERE條件句有用到這 個字段)上有1000筆重復的數據,表掃描也會比使用非聚集索引更快。

          查看圖形執行計劃上的數據表上的彈出式窗口時,請注意預估的資料行數(Estimated Row Count)”。這個數字是查詢優化器作出 的多少個數據行會被返回的最佳推測。如果執行了表掃描且預估的數據行數數值很高的話,就意味著返回的記錄數很多,查詢優化器認為執行表掃描比使用可用的非聚集索引更快。

          ·     Index Seek(索引查找):索引查找意味著查詢優化器使用了數據表上 的非聚集索引來查找數據。性能通常會很快,尤其是當只有少數的數據行被返回時。

          ·     Clustered Index Seek(聚集索引查找):這指查詢優化器使用了數據表上的聚集索引來查找數據,性能很快。實際上,這是SQL Server能做的最快的索引查找類型。

          ·     Clustered Index Scan(聚集索引掃描):聚集索引掃描與表掃描相似,不同的是聚集索引掃描是在一個建有聚集索引的數據表上執行的。和一般的表掃描一樣,聚集索引掃描 可能表明存在效能問題。一般來說,有兩種原因會引此聚集索引掃描的執行。第一個原因,相對于數據表上的整體數據行數目,可能需要獲取太多的數據行。查看預估的數據行數量(Estimated Row Count)”可以對此加以驗證。第二個原 因,可能是由于WHERE條件句中用到的字 段選擇性不高。在任何情況下,與標準的表掃描不同,聚集索引掃描并不會總是去查找數據表中的所有數據,所以聚集索引掃描一般都會比標準的表掃描要快。通常 來說,要將聚集索引掃描改成聚集索引查找,你唯一能做的是重寫查詢語句,讓語句限制性更多,從而返回更少的數據行。

          [7.0, 2000, 2005]

          絕大多數情況下,查詢優化器會對連接進行分析,按最有效率的順序,使用最有效率 的連接類型來對數據表進行連接。但并不總是如此。在圖形執行計劃中你可以看 到代表查詢所使用到的各種不同連接類型的圖標。此外,每個連接圖標都有兩個箭頭指向它。指向連接圖標的上面的箭頭代表該連接的外部表,下面的箭頭則代表這 個連接的內部表。箭頭的另一頭則指向被連接的數據表名。

           

          有時在多表連接的查詢中,箭頭的另一頭指向的并不是一個數據表,而是另一個連接。如果將鼠標移到指向外部連接與內部連接的箭頭 上,就可以看到一個彈出式窗口,告訴你有多少數據行被發送至這個連接來進行處理。外部表應該總是比內部表含有更少的數據行。如果不是,則說明查詢優化器所 選擇的連接順序可能不正確(下面是關于這個話題的更多 信息)

           

          首先,讓我們來看看連接類型。SQL Server可以使用三種不同的技術來連接資料表:嵌套循環(nested loop),散列(hash),以及合并(merge)。一般來說,嵌套循環是最快的連接類型,但如果不可能使用嵌套循環的話,則會用到散列或者合并作為合適的連接類型。兩者都比嵌 套循環連接慢。

           

          當連接大表時,則合并連接可能是最佳選項,而非嵌套循環連接。唯一的明確這一點的方式是對兩者都進行測試以查看哪一個最有效 率。

           

          如果你懷疑某個查詢速度慢的原因可能是因為它所使用的連接類型不理想,那么你可以使用連接提示來復蓋查詢優化器的選擇。在使用 連接提示之前,你需要花費一些時間去了解一下每種連接類型以及它們的工作方式。這是一個復雜的話題,超出了本文的討論范圍。

           

          查詢優化器選擇最有效率的連接類型來連接數據表。例如,嵌套循環連接的外部表應該是連接的兩個表中較小的那個表。散列連接也是 一樣,它的外部表應該是較小的那個表。如果你覺得查詢優化器選擇的連接順序是錯誤的,可以使用連接提示來復蓋它。

           

          很多情況下,唯一的確認使用連接提示改變連接類型或連接順序是提升還是降低了效能的方式,就是對它們進行測試,看看發生了什 么。[7.0, 2000, 2005]

          *****

           

          如果你的SQL Server有多個CPU,并且沒有修改SQL Server的默認設置來限制SQL Server使用服務器上所有CPU的能力,那么查詢優化器會考慮使用平行處 理(parallelism)來執行某些查詢。平行處理指在多個CPU上同時運行一個查詢的能力。很多情況下,一個運行在多個處理器上的查詢比僅運行在單個處理器上的查詢要快,但并不總是這樣。

           

          查詢優化器并不會總是使用平行處理,即使在它能使用的時候。這是因為查詢優化器在決定使用平行處理前會考慮到各種不同的因素。 例如當前SQL Server上處于活動狀態的連接數量,CPU忙碌程度,是否有足夠的內存來運行平行化查詢,需要處理的數據行數量,以及這個查詢的類型。查詢優化器收集到這些真實的數據 后,再決定平行處理是不是運行這個查詢的最佳選擇。你可能會發現,某次一個查詢沒有用到平行處理,但稍后某次再次運行同樣的查詢時,卻又用到了平行處理。

           

          有時,使用多個處理器所需的花費會大于使用它們能所能節省的資源。盡管查詢處理器的確會衡量使用平行查詢的正反兩面的影響,但 它的猜想并不總是正確的。

           

          如果懷疑平行處理防礙了某條查詢的性能,你可以使用OPTION (MAXDOP 1)提示來關閉該查詢的平行處理。

          決定是否使用平行處理的唯一方式是通過這兩種方式對查詢進行測試,看看發生了什么。[7.0, 2000, 2005]

          *****

           

          查看圖形執行計劃時,你可能會發現某個圖標的文字用紅色顯示,而非通常情況下的黑色。這意味著相關的表的一些統計數據遺失,統計數據是查詢優化器生成一個好的執行計劃所必須的。

           

          遺失的統計數據可以通過右鍵 這個圖標,并選擇創建遺失的統計資料來創建。這時會彈出創建遺失的統計數據對話框,通過它可以很容易地 創建遺失的統計數據。

           

          當可以選擇去更新遺失的統計 資料時,應該總是這樣做,因為這樣極有可能讓你正在分析的查詢語句從中獲得效能上的好處。[7.0, 2000, 2005]

          *****

           

          有時你會在圖形執行計劃上看到標識了”Assert”的圖標。這意味著查詢優化器正在驗證查詢語句是否有違反引用完整性或者條件約束。如果沒有,則沒有問題。但如果有的話,查詢優化器將無 法為該查詢建立執行計劃,同時會產生一個錯誤。[7.0, 2000, 2005]

          *****

           

          你常常會在圖形執行計劃上看到標識成書簽查找(Bookmark Lookup)”的圖標。書簽查找相當常見。書簽查找的本質是告訴你查詢處理器必須從數據表或者聚集索引中來查找它所需要的數據行,而不是從非聚集索引 中直接讀取。

           

          打比方說,如果一個查詢語句的SELECT,JOIN以及WHERE子句中的所有字段,都不存在于那個用來定位符合查詢條件的數據行的非聚集索引中,那么查詢優化器就不得不做額外的工作在數據表 或聚集索引中查找那些滿足這個查詢語句的字段。

           

          另一種引起書簽查找的原因是使用了SELECT *。由于在絕大多情況下它會返回比你實際所需更多的數據,所以應該永不使用SELECT *.

           

          從性能方面來說,書簽查找是不理想的。因為它會請求額外的I/O開銷在字段中查找以返回所需的數據行。

           

          如果認為書簽查找防礙了查詢的性能,那么有四種選擇可以用來避免它:可以建立WHERE子句會用到的聚集索引,利用索引交集的優勢,建立覆蓋的非聚集索 引,或者(如果是SQL Server 2000/2005企業版的話)可以建立索引視圖。如果這些都不可能,或者使用它們中的任何一個都會 耗用比書簽查找更多的資源,那么書簽查找就是最佳的選擇了。[7.0, 2000, 2005]

           

          有時查詢優化器需要在tempdb數據庫中建立臨時工作表。如果是這樣的話,就意味著圖形執行計劃中有標識成Index Spool, Row Count Spool或者Table Spool的圖標。

           

          任何時候,使用到工作表一般都會防礙到性能,因為需要額外的I/O開銷來維護這個工作表。理想情況下應該不要用到工作表。不幸的是并不能總是避免用到工作表。有時當使用工作表比其它選擇更有效 率時,它的使用實際上會增強性能。

           

          不論何種情況,圖形執行計劃中的工作表都應該引起你的警覺。應該仔細檢查這樣的查詢語句,看看是否有辦法重寫查詢來避免用到工 作表。有可能沒有辦法。但如果有的話,你就朝提升這個查詢的性能方面前進了一步。[7.0, 2000, 2005]

          *****

           

          在圖形執行計劃上看到流聚合(Stream Aggregate)圖標就意味著有對 一個單一的輸入進行了聚合。當使用了DISTINCT子句,或者任何聚合函數時,如AVG, COUNT, MAX, MIN,或者SUM等,流聚合操作就相當常見。 [7.0, 2000, 2005]

          *****

           

          查詢分析器與Management Studio不是唯一的可以生成顯示查詢執行計劃的工具。SQL Server Profiler也可以顯示執行計劃,但格式 是文本形式的。使用SQL Server Profiler來顯示執行計劃的一個優勢是,它能為實際運行的大量查詢產生執行計劃。如果使用查詢分析器和Management Studio,則一次只能運行一個。

           

          使用Profiler捕獲、顯示執行計劃時,必須使用如下的配置生成一個追蹤:

          捕獲事件

          ·     Performance: Execution Plan

          ·     Performance: Show Plan All

          ·     Performance: Show Plan Statistics

          ·     Performance: Show Plan Text

           

          顯示的字段

          ·     StartTime

          ·     Duration

          ·     TextData

          ·     CPU

          ·     Reads

          ·     Writes

           

          過濾條件

          ·     Duration。你會想指定最大的查詢執行時間,例如5秒鐘,由此避免得到太大量的數據。

           

          當然,你可以在你的追蹤中捕獲更多的沒有例在上面的信息,上面例出的只是一個指南而已。但必須記住不要去捕獲太多的數據,否 則,追蹤的運行會影響服務器的性能。[7.0, 2000, 2005]

          *****

           

          如果在查詢中使用了OPTION FAST提示,那就必須小心執行計劃的結果可能不是你所期望的。這時你所看到的執行計劃基于使用了FAST提示的結果,而不是整個查詢語句的實際執行計劃。

           

          FAST提示用來告知果詢優化器盡可能快地返回指定行數的數據行,即便這樣做 會防礙查詢的整體性能。使用這個提示的目的在于為使用者快速返回特定行數的記錄,由此讓他們產生速度非常快速的錯覺。。當返回指定行數的數據行后,剩余的 數據行按照它們通常的速度返回。

           

          因此,如果使用了FAST提示,那么生成的執行計劃只是基于那些FAST返回的數據行,而非查詢要返回的所有數據行。如果想看所有數據行的執行計劃,那么就必須移除這個FAST提示。[2000,2005]

          posted @ 2010-07-07 22:28 Eric_jiang 閱讀(1097) | 評論 (0)編輯 收藏

          之前沒哪次實踐過,只是聽一堆人說不可以或者不成功,今天測試了下,成功實現。
          OS:win2003
          Browse:IE6,Mozilla1.5,Netscape8.0,Friefox1.0,Opera8.51

          步驟:
          1、在iis新建站點3個www.goalercn.com(和 goalercn.com),img.goalercn.com,blog.goalercn.com
          2、在www.goalercn.com下建立文件testcookies.asp,代碼如下:
          <%
          Response.Cookies("Type") = "Test Cookies"
          Response.Cookies("Type").Expires = date()+30
          Response.Cookies("Type").Domain = ".goalercn.com"
          Response.Cookies("Type").Secure = False
          Response.Write Request.Cookies("Type")
          %>

           3、在ad.goalercn.com下建立文件testcookies.asp,代碼如下:
          <%Response.Write Request.Cookies("Type")%>

           4、在blog.goalercn.com下建立文件testcookies.asp,代碼同上
          5、因為是本機測試,修改hosts文件,把4個域名都指向到127.0.0.1,也就是添加如下內容:
              127.0.0.1     ad.goalercn.com
              127.0.0.1     blog.goalercn.com
              127.0.0.1     www.goalercn.com
              127.0.0.1     goalercn.com
          6、關閉所有瀏覽器,開ie,打開http://www.goalercn.com/demo/testcookies.asp,顯示出文本內 容:Test Cookies
          7、新建窗口,打開http://ad.goalercn.com/temp/testcookies.asp,顯示出文本內 容:Test Cookies
          8、新建窗口,打開http://blog.goalercn.com/temp/testcookies.asp,同樣顯示出如上文本內容
          9、換其他4個瀏覽器,都成功。

          注意點:
          1、Response.Cookies("Type").Secure = False,Secure屬性一定要是false,或者直接不執行這行,如果 Secure = True,則ad和blog的2級域名是取值不了。
          2、Response.Cookies("Type").Domain = ".goalercn.com",domain的值,我設置 為"goalercn.com",也就是沒有前面的點,在IE下成功
          其他4個瀏覽器沒測試。
          3、path我猜是不應該設置的。
          4、在局域網內其他機器上,修改host指向到我機器的IP,取值成功。
          5、在局域網另外一臺機器上架設ad.goalercn.com,把testcookies.asp文件copy過去,同時修改host到當前機器,取值 成功
          posted @ 2010-07-05 14:51 Eric_jiang 閱讀(928) | 評論 (3)編輯 收藏

          我們知道Struts2會將Action中的屬性存放到ValueStack對象中,在通過Action轉發的頁面中,我們可以通過Struts2的標簽<s:property/>來輸出這些值,但是這樣得到的值卻僅限于輸出顯示,不能進行進一步的操作,那么我們應該怎樣得到ValueStack中的值又能對它進行其他操作呢?

          首先,我們需要了解Struts2是將Action中的屬性全部封裝在一個叫做struts.valueStack的請求屬性中,然后我們就可以通過下面的代碼來獲取這些值了:

           

           someThing是Action中屬性值的名稱。

          posted @ 2010-06-30 21:18 Eric_jiang 閱讀(1625) | 評論 (1)編輯 收藏

          M

          S SQL2005對2000進行了很大的改進,而用戶關系這部分也變得相當復雜了,很多朋友都對此一知半解!下面,我將把我應用中總結的和大家分享下,先從概念入手,希望對不理解的朋友有點提示。

          今天我們要說的包括服務器登錄名Server Login,服務器角色Server Role,數據庫用戶DB User,數據庫架構DB Schema,數據庫角色DB Role 。以上幾個名詞應該從服務器與數據庫來區分,服務器包含一到多個數據庫,其中:

          服務器登錄名,指有權限登錄到某服務器的用戶;

          服務器角色,指一組固定的服務器用戶,默認有9組;

          • 登錄名一定屬于某些角色,默認為public
          • 服務器角色不容許更改
          • 登錄后也不一定有權限操作數據庫

          數據庫用戶,指有權限能操作數據庫的用戶;

          數據庫角色,指一組固定的有某些權限的數據庫角色;

          數據庫架構,指數據庫對象的容器;

          • 數據庫用戶對應于服務器登錄名以便登錄者可以操作數據庫
          • 數據庫角色可以添加,可以定制不同權限  
          • 數據庫架構,類似于數據庫對象的命名空間,用戶通過架構訪問數據庫對象

          而通過下圖可以讓這些概念清晰一些:

              

          即:

          1. 服務器登錄名屬于某組服務器角色;
          2. 服務器登錄名需要于數據庫的用戶映射后才擁有操作數據庫的權限
          3. 數據庫用戶屬于某組數據庫角色以獲取操作數據庫的權限
          4. 數據庫角色擁有對應的數據庫架構,數據庫用戶可以通過角色直接擁有架構
          5. 數據庫用戶有默認架構,寫SQL語句可以直接以“對象名”訪問
          6. 非默認架構則要以“架構名.對象名”訪問

          因此,新建一個非SA賬戶并建立數據庫的過程可以如下:

          1、新建登錄名Login1

           

          2、新建數據庫DB1

           

          3、新建DB1的架構Schema1


           

          4、新建BD1的用戶User1,登錄名對應Login1,默認架構選擇Schema1,角色選擇db_owner


           

          5、在登錄名Login1的屬性窗口里選擇“用戶映射”,勾選DB1,在用戶里填寫User1,默認架構選擇"Schema1"


           

          6、至此,新建表名會是Schema1.Table1,其他對象也如此


           


           

          7、當然還可以新建其他架構的對象Schema2,只有User1擁有該架構,一樣可以訪問,如Schema2.Table2

          值得注意的是,當為登錄映射數據庫用戶的時候,多個數據庫可以有相同名稱的用戶,而單獨為某個數據庫新建的用戶,如User1,則在其他數據庫里不允許同名。

          posted @ 2010-06-29 12:31 Eric_jiang 閱讀(640) | 評論 (0)編輯 收藏

          僅列出標題
          共57頁: First 上一頁 47 48 49 50 51 52 53 54 55 下一頁 Last 
          主站蜘蛛池模板: 鄂托克旗| 乌兰察布市| 小金县| 和田市| 独山县| 镇安县| 定南县| 乡宁县| 濮阳市| 崇州市| 高淳县| 长沙市| 砚山县| 两当县| 阿拉善盟| 神木县| 刚察县| 海淀区| 甘泉县| 竹北市| 汽车| 青海省| 台北县| 嘉鱼县| 嘉禾县| 定州市| 福贡县| 吉林省| 哈巴河县| 稻城县| 高青县| 怀来县| 厦门市| 迁西县| 漳平市| 苍梧县| 读书| 孟连| 扎兰屯市| 景德镇市| 武陟县|