结构集筛选哪个快?

spiritofdragon 2016-07-06 10:18:17
我懒得测试了,想请大家帮忙测试下,并发下 理性、有效的性能测试过程及结论。

问题:
从数据库里查询一个小型表(万级以下)或 中型表(万级以上,百万以下),全取出结果。再多的数据,就不符合场景了,不在这里讨论。
把结果集存入缓存,这样之前开关SQL的IO的效率就可以忽略了,不在这讨论。
下面对结构集做筛选操作的几种方法进行讨论研究。
1、存入DataSet的DataTable dt中。用 dt.select("col1 like '%xxx%'")筛选结构。
2、存入DataSet的DataTable dt中。用dt.DefaltView.Filter="col1 like '%xxx%'";
3、存入List<类mode> lst中。用lst.where(o=>o.col1.indexof(xxx)>=0).toList()
4、linq或EF的相应操作,我相信更慢,(这个结论对吧?)有测试过程最好。

比较上面4种方法哪种效果高?
1、要结论
2、有测试过程数据,更给分
3、小型表和中型表结论是否一致?
4、如果DataTable设了主键,会否提高筛选效率?
...全文
213 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
秋的红果实 2016-08-01
  • 打赏
  • 举报
回复
数据库有22000多条记录 我试过,有82万的库,可惜从数据库读入内存就很慢,这种情况,从数据库读取,建议楼主给库建立索引
秋的红果实 2016-08-01
  • 打赏
  • 举报
回复
直接的主要代码

try
{
    SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"].ToString());
    con.Open();
    DataSet ds = new DataSet();
    SqlDataAdapter da = new SqlDataAdapter("select * from tableN", con);
    da.Fill(ds);
    DataTable dt = ds.Tables[0];
    da.Dispose();
    con.Close();

    Stopwatch sw = new Stopwatch();
    sw.Start();
    //为了不相互干扰,是分2次执行的,每次具体时间不等,但大小关系确定
    var Res1 = dt.Select("Col like '%xxxxxxx%'");  //00:00:00.3655990
    //var Res1 = dt.DefaultView.RowFilter="Col like '%xxxxxxxx%'"; //00:00:00.2471333
    sw.Stop();
}
catch
{
    //...........
}


class Model
{
    public string Col1{set;get;}
    public string Col2 { set; get; }
    public DateTime Col3 { set; get; }
    public string Col4 { set; get; }
    public string Col5 { set; get; }

}

List<Model> list = new List<Model>();

try
{
    SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"].ToString());
    con.Open();
    SqlCommand com = new SqlCommand("select * from tableN", con);
    SqlDataReader dr = com.ExecuteReader();
    while(dr.Read())
    {
        list.Add(new Model() { Col1 = dr["Col1"].ToString().Trim(), Col2 = dr["Col2"].ToString().Trim(), Col3 = Convert.ToDateTime(dr["Col3"].ToString().Trim()), Col4 = dr["Col4"].ToString().Trim(), Col5 = dr["Col5"].ToString().Trim() });
    }
    com.Dispose();
    con.Close();
    
    Stopwatch sw = new Stopwatch();
    sw.Start();
    var Res1 = list.Where(o => o.Col1.IndexOf("xxxxxxxxx")>=0).ToList(); //00:00:00.6017635
    sw.Stop();
 }
catch
{
    //...........
}
写的比较匆忙
秋的红果实 2016-08-01
  • 打赏
  • 举报
回复
尽然是第2种最快,不是第3种! 测试过了
lshfong 2016-08-01
  • 打赏
  • 举报
回复
肯定3最快 like需要全表扫描
spiritofdragon 2016-08-01
  • 打赏
  • 举报
回复
引用 10 楼 sp1234 的回复:
我还是强调一次,动手测试是最基本的“素质”。写上7、8行代码产生测试数据,然后分别写上2行代码就能测试DataTable筛选表达式和Linq查询所需要耗费的时间值几分钱?! 面对最基本的两个信手拈来的查询表达式,不动手,只支嘴儿,这样的状态通常都不是你真实地在进行一个费时几个月的研发中,而是你只想临时起意想一个办法靠写一点点文字而赚一点关注的时候。
这确实是临时起意的一个想法。 但,在这里问,也是想知道,主流是怎么处理的。因为,现实中,一个人接触的永远都太少了。因为,吃闭门造车的亏也不少。 也说下,我最后使用的方案。把这个配置表的所有行的所有维度,作为key的一部分拼成,不重复的key,存入第三方缓存。 比如:key格式是 XXX_{0}_{1}_{2}_{3}....这样,0、1、2、3是where条件。这样,每个key就存的值,就不是集合了,是一个值。取时就快了,不用筛选了。
spiritofdragon 2016-08-01
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
我只从你的帖子看到几点: 1. 你不知道像 drt.select(...)、dataview.Filter=.... 这类字符串要付出代价去进行语法解释和临时编译,而产生的结果其实就模仿3、4。 2. 你不知道 Linq 其实为何物,你竟然不知道 3 中的where(....)就是linq,而4中的“linq或EF”也是linq。 3. 你不知道有索引和无索引的区别。你不懂“主键”跟你的那个查询表达式有没有什么关系?! 4. 你没有动手能力。连写个7、8代码的测试都动不动就说“我懒得测试了”。 5. 你比较喜爱发帖。贴别是拿不出自己的测试代码,但是忽悠别人的帖子。你可能是很适合博客园的那种发文章的风格。
1、确实不知道,所以想知道。 2、确实使用不多研究不多,所以想知道 3、sql的我知道,但C#的我不知道,所以想知道。(我知道DataTable可设primary key ,但不知道怎么设index。我的col1肯定不是primary key),所以,我想知道,即使设了primary key能有啥影响? 4、测试结论,很好得,但,自己的测试结论,不见得就是最好的方案。我能测试的,永远是我可预知的测试用例。但真正“要命”往往是人们预见不了的问题。所以才需要多问。当然,懒的另一层含义,也是,我花时间去测一个老东西的性能。往往是在重复工作,因为与此同时,你不知道,有更好用的东西已经诞生。我能从论坛中了解哪怕一丁点,也是收获。 5、学习方法不同,虽然也知道,自己的不一定好,但不是所有人都能有毅力去改变陋习的。
spiritofdragon 2016-08-01
  • 打赏
  • 举报
回复
引用 7 楼 xuanbg 的回复:
楼主,就单次执行时间而言,你认为最慢的,恰恰是最快的。因为你把全部数据加载到datatable或list的时间就远超直接查询获得结果的时间。 如果不算数据加载到内存的时间,第三种最快,因为list是强类型的,少了类型转换的时间
对,就单次而言,加载写入确实慢,但前提也说了。加载只是,缓存时,一次性的工作。即使再慢,一个小时才1次。使用时,只看筛选速度。谢谢结论,谢谢讨论。
spiritofdragon 2016-07-06
  • 打赏
  • 举报
回复
另外,还有啥更高效存结果集的方式(.Net环境内,程序中),也可以谈谈。 nosql/或框架上的建议就不要过多讨论了。
  • 打赏
  • 举报
回复
我还是强调一次,动手测试是最基本的“素质”。写上7、8行代码产生测试数据,然后分别写上2行代码就能测试DataTable筛选表达式和Linq查询所需要耗费的时间值几分钱?! 面对最基本的两个信手拈来的查询表达式,不动手,只支嘴儿,这样的状态通常都不是你真实地在进行一个费时几个月的研发中,而是你只想临时起意想一个办法靠写一点点文字而赚一点关注的时候。
  • 打赏
  • 举报
回复
我只从你的帖子看到几点: 1. 你不知道像 drt.select(...)、dataview.Filter=.... 这类字符串要付出代价去进行语法解释和临时编译,而产生的结果其实就模仿3、4。 2. 你不知道 Linq 其实为何物,你竟然不知道 3 中的where(....)就是linq,而4中的“linq或EF”也是linq。 3. 你不知道有索引和无索引的区别。你不懂“主键”跟你的那个查询表达式有没有什么关系?! 4. 你没有动手能力。连写个7、8代码的测试都动不动就说“我懒得测试了”。 5. 你比较喜爱发帖。贴别是拿不出自己的测试代码,但是忽悠别人的帖子。你可能是很适合博客园的那种发文章的风格。
Poopaye 2016-07-06
  • 打赏
  • 举报
回复
肯定3最快 而且肯定不应该是这样的o=>o.col1.indexof(xxx)>=0
software_artisan 2016-07-06
  • 打赏
  • 举报
回复
楼主,就单次执行时间而言,你认为最慢的,恰恰是最快的。因为你把全部数据加载到datatable或list的时间就远超直接查询获得结果的时间。 如果不算数据加载到内存的时间,第三种最快,因为list是强类型的,少了类型转换的时间
showjim 2016-07-06
  • 打赏
  • 举报
回复
Trie 图
  • 打赏
  • 举报
回复
Redis不能算? 叫我弄的话,首先DataSet不会作为内存存储的方式,我还是会选择List<Entity>的方式,这样更能预先进行排序(其实你可以认为就是主键作用了),然后适用各种查找算法(甚或者直接Hash来做映射) 其实上面都是扯淡,不同的查询条件,对应的插法不同,你硬要脱离数据库,其实也就是放弃了索引这个利器,而还想要效率的话,那也就是你自己要在程序里实现“索引”(算法),因为算法是可预料的,所以实际可能效率上还会高于“索引” 至于测试、结论啥的,拜托,你好歹也是SQL版蓝花,没有任何约束限制条件的测试有何意义?
正怒月神 2016-07-06
  • 打赏
  • 举报
回复
我只凭经验说一下。 一 首先1比2要快,dataView慢是出名的。 二 3和1比较的话,我个人偏向于3可能快。 三 你既然用了like并且%前置,那么索引就无效了
spiritofdragon 2016-07-06
  • 打赏
  • 举报
回复
引用 2 楼 fungchou 的回复:
没有测试,根据多年的.Net开发经验: 如果只进行一次查询,从空间利用和查询时间上,我倾向于第3种方法。 如果要进行多次查询,从查询效率和架构设计上,我倾向于直接从数据库查询,利用查询字段的数据库索引。
肯定是要频繁遍历该表,又要like ,用不了数据库的索引。又因为知道数据库io开销肯定比放缓存里,遍历结果集小。才提出这问题。 关键是,1、2、3哪个更快?
fungchou 2016-07-06
  • 打赏
  • 举报
回复
没有测试,根据多年的.Net开发经验: 如果只进行一次查询,从空间利用和查询时间上,我倾向于第3种方法。 如果要进行多次查询,从查询效率和架构设计上,我倾向于直接从数据库查询,利用查询字段的数据库索引。

110,552

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧