1. 程式人生 > 其它 >SQLSERVER 佔了500多M記憶體,原來的程式無法一次查詢出50多W資料了,記錄下這個問題的解決過程。

SQLSERVER 佔了500多M記憶體,原來的程式無法一次查詢出50多W資料了,記錄下這個問題的解決過程。

    今天需要使用“資料同步程式”將外網資料庫的FundYield 資料重新同步到內網,上次成功的一次將50W資料查詢了出來,但這次不行了。記得上次外網伺服器剩餘記憶體較多,SQLSERVER只佔用了150M,這次佔了500多M,程式無論如何也不能一次查詢出50W資料來,老是查詢超時,但這個資料著急要,只有想辦法了。

  系統使用每個表的最後修改日期(ZHXGRQ)欄位作為更新的標記,檢查了下資料,發現有51W多條資料都是 1999-1-1 ,除非程式將這51W條資料全部一次查詢出來,否則只有另外想辦法。看了下表結構,還有一個ID欄位(bigint型別),雖然不是主鍵,但不重複,這樣我們可以使用這個欄位作為“分頁

”的依據了,每次查詢個10-20W資料是沒有問題,於是將原來的實體類修改為下面的樣子:

namespace WFT_DataSyncModel 
{
  [Serializable()]
    public partial class FundYield : EntityBase, WcfMail.Interface.IDataSyncEntity
  {
    public FundYield()
    {
            TableName = "FundYield";
            EntityMap=EntityMapType.SqlMap;
            //IdentityName = "標識欄位名";
            //PrimaryKeys.Add("主鍵欄位名");
    PrimaryKeys.Add("jjdm");
    PrimaryKeys.Add("FSRQ");
            
            PropertyNames = new string[] { "ID","jjdm","jjmc","jjjc","dwjz","ljjz","FSRQ","QuarterYield","DayYield","WeekYield","WeekYieldPM","Month1Yield","Month1YieldPM","Month3Yield","Month3YieldPM","Month6Yield","YearYield","YearYieldPM","Year1Yield","Year1YieldPM","Year2Yield","Year3Yield","totalyield","bzc3","bzc6","bzc12","bzc24","BuyState","addtime","ZHXGRQ","DayYieldPM","Month6YieldPM","Year2YieldPM","Year3YieldPM","totalyieldPM","DayYieldCount","WeekYieldCount","Month1YieldCount","Month3YieldCount","Month6YieldCount","YearYieldCount","Year1YieldCount","Year2YieldCount","Year3YieldCount","totalYieldCount" };
            PropertyValues = new object[PropertyNames.Length]; 
    }
//...實體屬性在此省略
}

在實體類 FundYield 中,有一個實體對映型別屬性:

EntityMap=EntityMapType.SqlMap;//對映為自定義SQL查詢

預設情況下,應該是

EntityMap=EntityMapType.Table;//對映為表

資料更新實體類必須繼承一個數據更新介面:

WcfMail.Interface.IDataSyncEntity

好了,實體類的修改僅此以處,實體類對映指定為SqlMap型別,必須建立一個SqlMap配置檔案,檔名固定是 “EntitySqlMap.config”  ,下面是檔案內容:

程式碼 
<?xml version="1.0" encoding="utf-8"?>
<!--SQL-MAP 實體類自定義查詢配置檔案
SQL 語句不能使用 Select * from table 格式,必須指定跟實體類一致的欄位定義,否則可能發生難以預測的錯誤。
要生成實體類,請使用PDF.NET 實體類工具。
有關PDF.NET,請了解 http://www.pwmis.com/sqlmap
power by dth,2010.12.8
-->
<configuration>
  <Namespace name="WFT_DataSyncModel">
    <Map name="FundYield">
      <Sql>
      <![CDATA[
      SELECT    
 ID , jjdm , jjmc , jjjc , dwjz , ljjz , FSRQ , QuarterYield , DayYield , WeekYield , WeekYieldPM , Month1Yield , Month1YieldPM , Month3Yield , Month3YieldPM , Month6Yield , YearYield , YearYieldPM , Year1Yield , Year1YieldPM , Year2Yield , Year3Yield , totalyield , bzc3 , bzc6 , bzc12 , bzc24 , BuyState , addtime , ZHXGRQ , DayYieldPM , Month6YieldPM , Year2YieldPM , Year3YieldPM , totalyieldPM , DayYieldCount , WeekYieldCount , Month1YieldCount , Month3YieldCount , Month6YieldCount , YearYieldCount , Year1YieldCount , Year2YieldCount , Year3YieldCount , totalYieldCount  
      FROM FundYield where id < 400000
]]></Sql>
    </Map>
   
  </Namespace>
</configuration>

注意一下名稱空間和對映名稱必須和類的定義一致。

OK,所需的工作完成,我們只改了一下實體類的對映型別和編寫了一個實體類查詢檔案,編譯專案,重新發布,開始執行,剩下的只是每次修改一下配置檔案的查詢條件了,比如我現在正在使用的條件:

where ID>=600000 and ID<800000

最後的工作就是等待它執行完成,這個任務就OK了。

==================

總結:

使用面向物件的方法(OO)也可以很方便的處理“純資料問題”,資料只是物件的一部分,我們將資料放到物件中去處理,使得我們對新問題的處理變得很容易,這就是OO的美妙之處!