首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

有关大数据量的操作,该如何解决

2012-02-04 
有关大数据量的操作客户要求所有数据(万级)加载于Grid中显示(WINFORM),这势必导致数据库超时,服务器超时,U

有关大数据量的操作
客户要求所有数据(万级)加载于Grid中显示(WINFORM),这势必导致数据库超时,服务器超时,UI失去响应等等问题
现在普遍的做法是:
分批次获取数据,异步逐批加载到UI

所以在这想问问各位高手高高手,有更好的解决方案吗?请先细看要点和要求再做回答,谢谢。
要点:万级数据量, 加载于一个Grid中,不能分页,要一页显示,就像Excel一样。
要求:适用性高,因为还有好多地方涉及到这种问题;性能要求不需要太高,因为主要针对的是防超时,其次让用户知道数据在一点点的显示给他看就行了。


[解决办法]
如果我做这个应用,我会添加一个时间控件,interval设置为100ms(视客户端与数据库服务器连接所需时间而定),在请求数据时,先将这个grid能一页显示的数据从服务器取得,同时启动时间控件,当时间控件每触发一次时从服务器获得一批数据添加到grid中去,直到数据全部取完.估计用户在100ms内也不可能点击滚动条去拉到下一页去,这样可以让用户知道数据在不断加载(通过滚动条的中间拉块的变小),并且不致于一次传输太多数据而使客户端表观上显示处于停滞状态.
[解决办法]
参考 滚动条事件
当滚动条向下滚动到屏幕底部的时候自动填充下一屏数据。
[解决办法]

C# code
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication2{    public partial class Form1 : Form    {        System.Data.DataSet ds=new DataSet();        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();        public Form1()        {            InitializeComponent();            Form1.CheckForIllegalCrossThreadCalls = false;        }        private void button1_Click(object sender, EventArgs e)        {                conn.ConnectionString = "server=.;uid=sa;pwd=sqltest;database=media";                conn.Open();                using (System.Data.SqlClient.SqlCommand command = conn.CreateCommand())                {                    command.CommandText = "select * from v_test";                    using (System.Data.SqlClient.SqlDataAdapter adp = new System.Data.SqlClient.SqlDataAdapter(command))                    {                        adp.FillSchema(ds, SchemaType.Source);                    }                    this.dataGridView1.DataSource = ds.Tables[0];                    new System.Threading.Thread(new System.Threading.ThreadStart(Query)).Start();                                    }                   }        void Query()        {            using (System.Data.SqlClient.SqlCommand command = conn.CreateCommand())            {                command.CommandText = "select top 10000 * from v_test";                using (System.Data.SqlClient.SqlDataReader reader = command.ExecuteReader())                {                    while (reader.Read())                    {                        object[] v=new object[reader.FieldCount];                        reader.GetValues(v);                        ds.Tables[0].LoadDataRow(v, true);                        this.label1.Text = string.Format("{0}行",this.ds.Tables[0].Rows.Count);                    }                                    }                conn.Close();            }        }    }}
[解决办法]
那还是把树默认收起来吧,展开的时候再查询
[解决办法]
你要解决数据库超时的问题,说明这些数据肯定不能一次性的从数据库读取出来。那就肯定要分次读取了。

你需要根据实际情况考虑如何分次去读,是按固定记录量分开,还是根据上下级树型结构分。这于使用时候的需求有关

至于告诉用户正在进行处理,只需要有一个进度条就行了

做成多线程的,防止UI无相应
[解决办法]
那还是把树默认收起来吧,展开的时候再查询
[解决办法]
启动多个线程去取数据,每个线程取完数据的时候,UI刷新它那一块,相当于异步响应。每个线程取自己的那部分数据,这样用户体验好一些。

[解决办法]
怕超时的话由两方面入手,一是检查当前的查询SQL速度能否再提升,包括优化写法和增加索引。二是把读取动作分解,一次只读一部分,分多次读完。参考分页的读取方法,用子线程读取一部分填充一部分,这样就不会让用户等到所有数据加载完成才能看到了。
------解决方案--------------------


多线程取数据 默认取出树的根节点 子节点点击获取数据!

热点排行