IQueryable型別的物件要Cache時必須注意的事

IQueryable型別的物件要Cache時必須注意的事

在前不久才知道Cache的觀念,並知道Cache要怎麼使用。

因此為了網頁的效能,就開始在一些比較不常改變,但需要去撈資料的地方

做了Cache的動作。但今天寫著寫著,突然想到一件事情:

在使用Linq時,為了避免資料全部倒回來,因此都會加上一個AsQueryable()的方法,

在最後要使用到此物件時,才去撈資料庫的資料。

但問題就是,如果Cache一個IQueryable的物件,那對效能會有幫助嗎?

由於心生疑惑,因此就寫了一個小測試來看看

(由於本篇重點不在Cache的使用,因此我就用最隨便的方式寫了。)


public ActionResult Index()
{
     MyDataContext db = new MyDataContext();

     var model=HttpContext.Cache["Model"] as IQueryable<文章>;

     if (model == null)
     {
         model = db.文章.AsQueryable();

         HttpContext.Cache["Model"] = model;
     }
         
     return View(model);
     
}

Code非常簡單,在第5~7行的時候檢查Cache["Model"]裡有沒有東西

如果沒有的話,就在第9~11行去撈資料並存到Cache裡面,然後丟回View

由於Linq延遲載入的關係,因此一直到整個action執行完畢,都沒有真正去

SQL撈資料,而是等到View上需要資料時,才會對SQL下指令。

用個偵錯來看

image

在此時存進Cache的不過是個IQueryable的物件,只有對SQL所下的指令,並沒有資料。

因此在View的時候,只要reload幾次,就會對sql下幾次select的動作。

image

這樣對效能的幫助不大,因此如果真的要使用的話,要先將資料撈回,再Cache起來


public ActionResult Index()
{
      MyDataContext db = new MyDataContext();

      var model=HttpContext.Cache["Model"] as IEnumerable<文章>;

      if (model == null)
      {
          model = db.文章.ToList();

          HttpContext.Cache["Model"] = model;
      }

      return View(model);
}

這樣的話,除了第一次會對資料庫讀取資料,之後只要Cache沒有消失

就不會再去對資料庫做動作,對效能應該幫助比較大。

 

p.s 對於IQueryable或Linq技術熟悉者,應該會覺得本文是篇很無聊的文章,

     目的只是在於提醒Cache時要注意Cache的東西對程式效能有沒有幫助。

p.s2 在寫這種偏向於觀念的文章都會有點怕怕的,擔心自己的錯誤觀念誤導別人

        ,因此如果有不對的地方,麻煩大家多指教囉。