优化中发现一个存储过程执行20秒通过profiler 抓取发现时间主要消耗在一个select * from 表,那么问题来了select几万数据竟然花了将近20秒?

    问题排查清了程序前端使用了datareader获取数据,那么datareader对数据库有什么影响呢?下面来做个实验测试一下。首先我们创建测试表并插入200条数据。

    

 CREATE TABLE [dbo].[table_2](
[a] [int] NULL,
[b] [datetime] NULL,
[c] [uniqueidentifier] NOT NULL
) insert into [table_2]
select 1,getdate(),newid()
go 200

编写一段简单的C#小程序,使用datareader读取一个select * from table 在datareader的循环中我们设置线程等待50毫秒。System.Threading.Thread.Sleep(50);

    

protected void Button1_Click(object sender, EventArgs e)
{ //SqlCommand sqlCmd = new SqlCommand("p_datareader_test", con);
//sqlCmd.Connection = con;
//sqlCmd.CommandType = CommandType.StoredProcedure;//设置调用的类型为存储过程 //SqlParameter sqlParme = new SqlParameter();
//sqlParme = sqlCmd.Parameters.Add("@p", SqlDbType.Int);
//sqlParme.Direction = ParameterDirection.Input;
//sqlParme.Value = 0; //SqlDataReader reader = sqlCmd.ExecuteReader(); SqlConnection con = new SqlConnection();
con.ConnectionString = "server=vpc-new3;database=replication;uid=sa;pwd=sa_123456";
DataTable dt = new DataTable(); //SQL直接查询测试-------------------------------
con.Open();
SqlCommand com = new SqlCommand();
com.Connection = con;
com.CommandType = CommandType.Text;
com.CommandText = "select * from table_2"; SqlDataReader reader = com.ExecuteReader(); DataRow dtr = dt.NewRow () ; try
{
DataTable objDataTable = new DataTable();
int intFieldCount = reader.FieldCount;
for (int intCounter = ; intCounter < intFieldCount; ++intCounter)
{
objDataTable.Columns.Add(reader.GetName(intCounter), reader.GetFieldType(intCounter));
}
objDataTable.BeginLoadData(); object[] objValues = new object[intFieldCount];
while (reader.Read())
{
//系统等待
System.Threading.Thread.Sleep();
reader.GetValues(objValues);
objDataTable.LoadDataRow(objValues, true);
}
reader.Close();
objDataTable.EndLoadData(); GV .DataSource = objDataTable;
GV.DataBind(); }
catch (Exception ex)
{
throw new Exception("转换出错!", ex);
}
reader.Close();
con.Close(); }

    下面来测试执行一下:

    点击按钮出发btnclick

  

    

    执行时间0毫秒?竟然不像想象中的时间会长? 这是为什么呢?

    

    测试继续! 我们加大数据,继续添加200条。

    

insert into [table_2]
select 1,getdate(),newid()
go 200

    

    测试效果一样0毫秒。

    继续增加200 条 目前数据600条

    

    看一下效果:

    

    效果神奇的出现了 600条记录的查询需要12秒!!

    我们再一次执行观察一下竟然12秒才执行完肯定会有等待!

    

select wait_type,brt.text from sys.dm_exec_requests br
OUTER APPLY sys.dm_exec_sql_text(br.sql_handle) AS brt
where brt.text like '%table_2%'

    

    没错就是他 传说中的ASYNE_NETWORK_IO

    

    

    疑问:按照之前的理解datareader 一次只是读取一条记录...那么为什么我400条记录的时候就不会出现等待呢?

    想到了发送的网络包大小,mssql默认为4096

    

    那么我们继续用200条数据测试这次加大表的长度

    

drop table table_2

CREATE TABLE [dbo].[table_2](
[a] [int] NULL,
[b] [datetime] NULL,
[c] [uniqueidentifier] NOT NULL,
d char(4000)
) insert into [table_2]
select 1,getdate(),newid(),'test'
go 200

    再次测试执行观察效果

    

    好吧我猜对了....

    后续用dataset接收返回结果就不会出现上述问题,所以如网上所说datareader接收结果集使用要注意接收结果后要避免在循环中有大量的耗时处理。

select * from table 时间长的更多相关文章

  1. Go基础系列:为select设置超时时间

    Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 After() 谁也无法保证某 ...

  2. 由select * from table where 1=1中的1=1说开数据库

    众多网站都有select * from table where 1=1此类语句的介绍,并且,针对该类语句,讲得实在是让人越看越迷茫(一个抄袭一个的,简直不像话),不知道是在说什么,导致很多新手不得要领 ...

  3. android MotionEvent 获取长按压时间长

    思路: 1.记录ACTION_DOWN的aX, aY坐标: 2.在ACTION_MOVE判断是否移动,移动则取消记录时间,没移动就记录: 3.记录时间,按下坐标,移动坐标分别显示在TextView a ...

  4. wex5 开机图片时间长

    作用: 控制刚打开图片 时间长 修改config.xml  地址:F:\wex\model\Native\templates\advanced 延迟的时间是在本地app的 config.xml中修改, ...

  5. IE8 下 select option 内容过长 , 展开时信息显示不全解决办法

    IE8 下 select option 内容过长 , 展开时信息显示不全 , 简单折衷的方式就是给 option 加上 title 属性 , 但是又不想一个个的修改,怎么办呢,代码如下 : //sel ...

  6. select * from table where 1=1

    转自:http://www.dzwebs.net/2418.html 我们先来看看这个语句的结果:select * from table where 1=1,其中where 1=1,由于1=1永远是成 ...

  7. select * from table where 1=1让您茅塞顿开(转)

    在很多网站上,都经常看到select * from table where 1=1这样的一种查询语句: 这是一种怎样的查询语句呢?首先说明,1=1不是查询语句中的任何关键词,所以,请您放心,不管你会不 ...

  8. 普通用户授予select any table 权限

    基于应用的需要,让普通用户有访问sys表的权限,于是就想到了select any table 的权限,可是当授权以后发现还是不能访问sys的表,经过查一系列资料,发现select any table不 ...

  9. Win10正式版开机慢怎么办 开机黑屏时间长怎么办

    升级Win10正式版后开机速度慢.黑屏时间长怎么解决呢?其实我重要是由Win10正式版所提供的“快速启动”功能与电脑显卡驱动.电源管理驱动不兼容所造成的.下面就与大家分享一下针对Win10正式版开机速 ...

随机推荐

  1. android BluetoothLE 多个 setCharacteristicNotification writeCharacteristic 失效

    如果在搜索完服务后,执行多个 setCharacteristicNotification 或 writeCharacteristic 操作,某些操作可能会无效.需要在中间等待一些时间,真是一个大坑! ...

  2. 第三次作业——《K米评测》

    第三次作业--<K米评测> 一.调研.评测 上手体验 APP的图标做的不错,一眼就知道和KTV唱歌相关的 点进去就是连接包箱的界面和直播界面,把软件最重要的两个功能展示出来了,一目了然 热 ...

  3. Servlet下载文件和http响应

    下载文件等: 1.得到公共的内容ServletContext sc = this.getServletContext(); 2.在链接名字后面加个? 一个参数?参数1=值 两个参数?参数1=值& ...

  4. ES6中的var let const应如何选择

    javascript世界里面的每个人都在说有关ECMAScript 6 (ES6,也称作ES 2015)的话题,对象的巨大变化 ( 类 , super() , 等), 函数 (默认参数等), 以及模块 ...

  5. 怎么实现CSS限制字数,超出部份显示点点点.

    如何实现CSS限制字数,超出部份显示点点点... <div style="width:200px; white-space:nowrap;overflow:hidden;text-ov ...

  6. 进阶——scrapy登录豆瓣解决cookie传递问题并爬取用户参加过的同城活动©seven_clear

    最近在用scrapy重写以前的爬虫,由于豆瓣的某些信息要登录后才有权限查看,故要实现登录功能.豆瓣登录偶尔需要输入验证码,这个在以前写的爬虫里解决了验证码的问题,所以只要搞清楚scrapy怎么提交表单 ...

  7. 使用django-admin.py 时出错

    我在安装好django后,运行django-admin.py 时出现两处错误: 一.当你在dos命令下输入django-admin.py 时不会运行,而是以记事本的方式打开了. 解决办法:找到你的dj ...

  8. java获取文件名的三种方法

    import java.io.File; import java.util.Arrays; public class FileName { /** * @param args */ public st ...

  9. 使用jigdo下载debian [windows环境下]

    使用jigdo下载debian  本文地址:http://www.cnblogs.com/yhLinux/p/4104451.html 准备工作: 下载jigdo:http://atterer.org ...

  10. Sprint评审会议不是Sprint演示会议

    最近,Innolution公司的执行总监.Essential Scrum的作者Ken Rubin在其公司博客上撰写了一篇题为It’s a Sprint Review Not a Sprint Demo ...