做了一个表读取的效率测试...

tkscascor 2010-01-14 11:31:03
因为要考虑一个大数据量的操作问题,,,所以
做了一个表读取的效率测试...
使用c# 来判断的,各位高手可以无视我的测试代码,
看我的sql语句跟测试结果就行了
*** 测试数据***/
数据量20w,
左连接获取,
主表tb2
CREATE TABLE [tb2] (
[id] [bigint] IDENTITY (1, 1) NOT NULL ,
[tb1_id] [bigint] NULL ,
[type] [int] NULL ,
CONSTRAINT [PK_tb2] PRIMARY KEY CLUSTERED
(
[id]
) ON [PRIMARY]
) ON [PRIMARY]
GO
从表 tb1
CREATE TABLE [tb1] (
[ID] [bigint] IDENTITY (1, 1) NOT NULL ,
[testname] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[stoploss] [int] NULL ,
[stopprofit] [int] NULL ,
CONSTRAINT [PK_tb1] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
两者的关系,多对一, 简单来说 就是2对一.
/****以一条关联数据为例***/
--tb2
id tb1_id type
1 1 101(指向tb2的stoploss 字段)
2 1 102(指向tb2的stopprofit字段)
--tb1
id testname stoploss stopprofit
1 test 3 5
/****以一条关联数据为例***/


   /// <summary>
/// 获取消耗时间
/// 2010-1-13 by ascor
/// </summary>
/// <param name="strSql"></param>
/// <returns></returns>
private TimeSpan getTime(string strSql)
{
GC.Collect();
GC.WaitForPendingFinalizers();
DateTime dt = DateTime.Now;
DataSet ds = Query(strSql);
TimeSpan ts = DateTime.Now - dt;
return ts;
}

/// <summary>
/// 执行查询语句,返回DataSet
/// 2010-1-13 by ascor
/// </summary>
/// <param name="SQLString">查询语句</param>
/// <returns>DataSet</returns>
public DataSet Query(string SQLString)
{
using (SqlConnection connection = new SqlConnection(strconnect))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);
command.Fill(ds, "ds");
}
catch (SqlException ex)
{
throw new Exception(ex.Message);
}
finally
{
connection.Close();
}
return ds;
}
}

//测试方法1,全部字段获取
protected void Button1_Click(object sender, EventArgs e)
{
StringBuilder strSql = new StringBuilder();
strSql.Append(@"select a.id,b.id,b.testname,b.stoploss,b.stopprofit, a.type
from tb2 a left join tb1 b
on a.tb1_id=b.id");
this.lbl_function1.Text = getTime(strSql.ToString()).ToString();
}
//测试方法2,使用case获取需要字段
protected void Button2_Click(object sender, EventArgs e)
{
StringBuilder strSql = new StringBuilder();
strSql.Append(@"select a.id,b.id,b.testname,a.type,case a.type when 101 then b.stoploss when 102 then b.stopprofit end params
from tb2 a left join tb1 b
on a.tb1_id=b.id");
this.lbl_function2.Text = getTime(strSql.ToString()).ToString();
}

/*****测试结果*****/
方法2始终比方法1测试快0.05秒-0.1秒范围内
粗劣一看,方法1获取多了一个字段, 但是方法2的select在每次读取记录的时候都是多了一次判断操作.虽然有聚索引, 但是因为没有使用where, 这两种方法的获取应该都是堆获取.不存在二叉树的获取方式,也就是说两种获取方式每次获取应该是顺序获取的.不同的是方法2在读取的时候多了一个判断, 我猜想方法2快的原因是不是,判断完后调用(或者说借用)了索引直接指向了说需要的字段.... 只是猜测, 还望有谁可以告诉我真正的原因

附加测试.


/***测试代码**/
//方法5
protected void Button5_Click(object sender, EventArgs e)
{
StringBuilder strSql = new StringBuilder();
strSql.Append(@"select a.*
from tb2 a where a.id>0");
this.lbl_function5.Text = getTime(strSql.ToString()).ToString();
}
//方法6
protected void Button6_Click(object sender, EventArgs e)
{

StringBuilder strSql = new StringBuilder();
strSql.Append(@"select a.*
from tb2 a ");
this.lbl_function6.Text = getTime(strSql.ToString()).ToString();
}

/**** 测试结果***/
根据我对索引的理解, 理论上说方法5应该比方法6快.
因为在没有使用where进行检索数据的时候, 所有的读取是不依靠索引的, 直接堆获取,这是根据msdn的sql上对索引的解释得来的分析, .但是事实结果是 方法5与6的读取速度是完全一样的.




这两个测试结果 ,我都很郁闷,跟我理解的有出入, 望高人可以给我解释一下.. 代码有点长,且冗余,请慢慢看!


...全文
108 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
tkscascor 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 orchidcat 的回复:]
利用SQL自带的性能监控,已经达到了要求。如果用外围的C#等自己计算。 也要消耗系统资源。
不利于评估哦!

个人意见!仅供参考!
[/Quote]
因为需要对获取的数据进行操作, 所以要评估的效率问题不仅仅是sql的问题, 现在只是截取了关于sql测试的代码.
yananguo_1985 2010-01-14
  • 打赏
  • 举报
回复
帮顶!
tkscascor 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wzy_love_sly 的回复:]
鄙视一下楼主

个人意见!仅供参考!
[/Quote]

接受你的鄙视. .... 我这样测试有目的的撒... 用c# 测试,是因为还有别的需求....
wzy_love_sly 2010-01-14
  • 打赏
  • 举报
回复
鄙视一下楼主

个人意见!仅供参考!
Mr_Nice 2010-01-14
  • 打赏
  • 举报
回复
利用SQL自带的性能监控,已经达到了要求。如果用外围的C#等自己计算。 也要消耗系统资源。
不利于评估哦!

个人意见!仅供参考!
ws_hgo 2010-01-14
  • 打赏
  • 举报
回复
gz
pt1314917 2010-01-14
  • 打赏
  • 举报
回复

个人认为:
方法1比方法2要多返回一些字段的数据,应该1比2要慢一些,
但又因为2比1多一些逻辑判断操作。所以在这个地方1比2要慢一点。所以从情况上来说是两者相当。
至于最后到底谁比谁快。这个就要问微软了。是返回多一个字段用的时间多,还是判断用的时间多

方法5和方法6,照常理方法5比方法6会快一些,因为方法5有条件,返回的数据应该会少一些。
但现在你tb1表中没有id<=0的数据。也就是说id>0返回了全部数据。所以跟方法6没什么区别了。。。


--小F-- 2010-01-14
  • 打赏
  • 举报
回复
写这个还不如看执行计划
andysun88 2010-01-14
  • 打赏
  • 举报
回复
select a.* from tb2 a where a.id>0
select a.* from tb2 a

他们两个我在sql 的执行计划中,两者的开销都是50%,一样的,你测试没有问题
tkscascor 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fredrickhu 的回复:]
写这个还不如看执行计划
[/Quote]
执行计划中,两个查询消耗的成本的数据是一样的! 方法2多了computer scalar, 但是消耗成本是0%

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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