一切为了DotNet

念天地之悠悠,独怆然而涕下

 

关于大数据量异构数据间数据传输及简单的多线程

     这几天写东西遇到了大量数据从informix导出到sql的问题,开始的反映就是使用DTS,但是需要在程序中每天重复这个动作,而且有些表是要覆盖导出的,有些表则是增量导出的,在DTS中不好控制,而且客户也不希望使用DTS来实现,所以就直接把数据取到内存中的DataSet,使用DataAdapter来insert到sql中也不错,开始测试了一万条左右的数据,列数为100列左右,竟然使用了差不多一分种的时间,这样算起来的话,我岂不是要导个200分钟?而且这是取出来放到内存中的,数据不大还可以,否则再多的内存也不够用的。
     否定DataSet,那就使用DataReader来实现吧,这样内存中只会存放当前一条记录,而且DataReader是向后只读的,速度很快,把每读出来的记录Insert到Sql中,这样速度还是和使用DataAdapter差不多,大概能快那么一点。
 1public void InsertIIM(OleDbTransaction tIfx,SqlTransaction tSql)
 2        {
 3            //string strSql = "select  *  from IIM where serialcolumn not in (select pk from tabdtsc where tab='IIM')";
 4            string strSql = "select  *  from IIM ";
 5
 6            OleDbCommand olecmd = new OleDbCommand(strSql,this.cnnIfx,tIfx);
 7
 8            System.Data.OleDb.OleDbDataReader oledr;
 9            oledr = olecmd.ExecuteReader(); 
10            
11            SqlCommand cmd = new SqlCommand();
12            cmd.Transaction = tSql;
13            cmd.Connection =  this.cnn;
14
15            cmd.CommandText = "truncate table IIM ";
16            cmd.ExecuteNonQuery ();
17
18            string strIntSql = "";
19            object[] objColumn = new object[oledr.FieldCount];
20            while (oledr.Read())
21            {
22                strIntSql ="insert into iim values(";
23                oledr.GetValues(objColumn);
24                for(int i=0;i<objColumn.Length-1;i++)
25                {
26                    if(objColumn[i].GetType().ToString()=="System.DBNull")
27                        strIntSql+=" null,";
28                    else
29                        strIntSql+="'"+objColumn[i].ToString()+"',";
30                }

31
32                
33                if(objColumn[objColumn.Length-1].GetType().ToString()=="System.DBNull")
34                    strIntSql+=" null)";
35                else
36                    strIntSql+="'"+objColumn[objColumn.Length-1].ToString()+"')";    
37
38                cmd.CommandText = strIntSql;
39                cmd.ExecuteNonQuery();                
40            }

41            oledr.Close();
42        }
     这样虽然实现了,速度还是不能让人满意,于是使用了多线程,因为是从多个表中取数据,insert到sql对应的表中,所以对于每个表开了一个线程,由于使用的是oledb连接的informix数据库,使用了事务,而提示不支持并行事务,所以对于每个线程创建了一个informix的连接,最后速度当然是大大的提高了。
 1Thread[] m_thdX = new Thread[5];
 2
 3            m_thdX[0= new Thread(new ThreadStart(InsertFSO));
 4            m_thdX[0].Start();
 5        
 6            m_thdX[1= new Thread(new ThreadStart(InsertILI));
 7            m_thdX[1].Start();
 8
 9            m_thdX[2= new Thread(new ThreadStart(InsertMBM));
10            m_thdX[2].Start();
11        
12            m_thdX[3= new Thread(new ThreadStart(InsertIIM));
13            m_thdX[3].Start();
14
15            m_thdX[4= new Thread(new ThreadStart(InsertITH));
16            m_thdX[4].Start();
17
18            m_thdX[0].Join();
19            m_thdX[1].Join();
20            m_thdX[2].Join();
21            m_thdX[3].Join();
22            m_thdX[4].Join();
    因为在所有线程执行完毕后会有其他的操作,所以需要使用join()方法来等待线程结束。
    补充一点,不要忘记使用lock(this),来进行同步。
    搞定,不过最后不要忘记关闭informix的连接。

posted on 2005-07-20 11:18  一切为了DotNet  阅读(792)  评论(0编辑  收藏  举报

导航