从datatable(缓存对象)与数据库中搜索项目

时间:2013-10-26 13:23:38

标签: c# asp.net

当前我有一个存储在数据库中的大数据。

这组数据(3000条记录)将由用户经常检索。

目前我正在使用的方法是:

  1. 从数据库中检索这组记录
  2. 转换为数据表
  3. 存储到缓存对象
  4. 根据查询

    从此缓存对象中搜索结果
    CachePostData.Select(string.Format("Name LIKE '%{0}%'", txtItemName.Text));
    
  5. 将结果绑定到转发器(每页显示40条记录的分页)

  6. 但是我注意到性能不好(每次请求大约4秒)。所以,我想知道有没有更好的方法呢?或者我应该立即从数据库中检索每个查询的结果?

3 个答案:

答案 0 :(得分:3)

DataTable.Select可能不是搜索内存缓存的最有效方法,但它肯定不需要4秒或类似搜索3000行。

第一步是找出性能瓶颈所在。我认为这与搜索缓存无关,但您可以轻松找到,例如代码类似于:

var stopwatch = Stopwatch.StartNew();
var result = CachePostData.Select(string.Format("Name LIKE '%{0}%'", txtItemName.Text));

WriteToLog("Read from cache took {0} ms", stopwatch.Elapsed.TotalMilliseconds);

其中WriteToLog跟踪某处(例如System.Diagnostics.Trace,System.Diagnostics.Debug或日志框架,如log4net)。

如果您正在寻找缓存的替代方法,您可以简单地缓存实体对象的通用列表,并使用Linq搜索列表:

var result = CachePostData.Select(x => x.Name.Contains(txtItemName.Text));

这可能稍微有点效率(例如,它不需要解析“NAME LIKE ...”过滤器表达式),但同样,我不认为这是你的瓶颈。

答案 1 :(得分:2)

我认为使用datatable会更有效率,因为这会降低数据库服务器上的命中率。您可以将数据表存储在缓存中,然后重复使用它。这样的事情: -

public DataTable myDatatable()
{
   DataTable dt = HttpContext.Current.Cache["key"] as DataTable;
   if(dt == null)
   {
       dt = myDatatable();
       HttpContext.Current.Cache["key"] = dt;
   }
   return dt;
}

同时检查SqlCacheDependency

您也可以在某个特定时间间隔清除缓存,如下所示: -

HttpContext.Current.Cache.Insert("key", dt, null, DateTime.Now.AddHours(2), 
System.Web.Caching.Cache.NoSlidingExpiration);

同时检查DataTable caching performance

答案 2 :(得分:2)

如果不知道您实际期望的数据库上有多少匹配,就很难为您的问题声明一个正确的解决方案。对于大多数情况,我不会将数据缓存在ASP.NET缓存中进行过滤,因为使用DataTable.Select进行搜索基本上执行表扫描并且无法利用数据库索引。除非您遇到非常繁重的负载,否则大多数数据库服务器应该能够以比在.NET中过滤DataTable更少的延迟执行此任务。

如果您的数据库支持全文搜索(即MSSQL或MySQL),您可以在名称列上创建全文索引并查询。全文搜索应该为这些类型的LIKE查询提供更快的响应类型。

通常,缓存数据以便更快地访问是好的,但在这种情况下,DataTable在搜索数据方面很可能不如数据库服务器。您仍然可以使用缓存更快地显示未过滤的数据,而无需访问数据库。