0 0

sql server数据库中,从一张表复制数据到另一张表,并新表多添加几个字段,由于数据量的问题,求高效率30

题目:
     表A   字段 A1(主键,自增长) A2  A3     -- 2000万行数据
     表B   字段 B1(主键,自增长) B2 B3     --  100万行数据

要求:
     将表A的数据复制到表C中,并且表C中多两个字段  isB1  isB2,即     A1  A2  A3  isB1   isB2字段

简单概述我的做法:
  while循环(2000万次)
      添加表C数据,执行修改新字段值(isB1,isB2[若A1=B1,则 isB1=1,否则isB1=0]).

问题:
    当执行到第10万条左右时,效率非常低,加一条至少需要10秒的时间,并且有时候会出现断开连接的问题。

目的:
    实现表C的数据,并要求高效率。

      急求解!!!!
2011年5月08日 22:14

9个答案 按时间排序 按投票排序

0 0

select * into c from a;
alter table c add isB1 char default '0';
alter table c add isB2 char;
update c set isB1='1' where A1 in (select B1 from b);

2011年5月17日 14:27
0 0

这是一个子类的实现:

package com.autonavi.po;

import com.autonavi.batch.LayerBatchSetter;
import com.autonavi.template.MoveTemplate;

/**
 * xx功能Action类
 * @Title:
 * @author shuo.cao
 * @Company: Autonavi
 * @date: 2011-5-16 上午11:02:06
 */
public class Layer extends MoveTemplate<LayerBatchSetter> {

	@Override
	public void setCountSql() {
		this.countSql = "select count(0) from EP_POILAYERS" ;
	}

	@Override
	public void setInsertSql() {
		this.insertSql = "insert into T_LAYERS (" +
				"ID,LAYER_NAME,LAYER_DESC,USE_STATUS,CTDATE,PROPERTY,IS_OPEN_FOR_UP,IS_OPEN_FOR_DOWN," +
				"IS_SHARED,USAGE_FLAG,IS_SHOW,IS_LOAD,LAYER_LEVEL" +
				") values(?,?,?,?,to_date(?,'yyyy-MM-dd HH24:mi:ss'),?,?,?,?,?,?,?,?)" ;
		
	}

	@Override
	protected void setSelectSql() {
		//构造查询语句
		StringBuilder sql = new StringBuilder() ;
		sql.append("select * from (") ;
		sql.append("select rownum r, p.* from EP_POILAYERS p where rownum <= ") ;
		sql.append(MoveTemplate.END_ROW_NUM + " ") ;
		sql.append("order by EPLYRID asc) ") ;
		sql.append("where r > ") ;
		sql.append(MoveTemplate.START_ROW_NUM) ;
		
		this.selectSql = sql.toString() ;
	}

}


还有另外的那个setter类:
package com.autonavi.batch;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;

import com.autonavi.util.StringUtil;

/**
 * xx功能Action类
 * @Title:
 * @author shuo.cao
 * @Company: Autonavi
 * @date: 2011-5-16 上午11:05:01
 */
public class LayerBatchSetter implements BatchPreparedStatementSetter {
	
	private List<Map<String, Object>> list = null;
	
	public LayerBatchSetter(List<Map<String, Object>> list){
		this.list = list ;
	}

	public int getBatchSize() {
		return list.size();
	}

	public void setValues(PreparedStatement pstmt, int i) throws SQLException {
		
		Map<String, Object> obj = list.get(i) ;
		
		pstmt.setString(1, obj.get("EPLYRID")+"");
		pstmt.setString(2, obj.get("LAYERNAME")+"");
		pstmt.setString(3, obj.get("LAYERNAME")+"");
		pstmt.setInt(4, 0);//用户状态
		pstmt.setString(5, StringUtil.ObjSubString(obj.get("CTDATE"),0,19));
		pstmt.setString(6, "");//图层属性
		pstmt.setInt(7, 1);//向上开放
		pstmt.setInt(8, 1);//IS_OPEN_FOR_DOWN
		pstmt.setInt(9, 1);//IS_SHARED
		pstmt.setInt(10, 1);//USAGE_FLAG
		pstmt.setInt(11, 1);//IS_SHOW
		pstmt.setInt(12, 1);//IS_LOAD
		pstmt.setInt(13, 1);//LAYER_LEVEL

	}

}

2011年5月16日 15:41
0 0

介绍下我的解决办法:

package com.autonavi.template;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 数据迁移功能抽象类
 * @Title:
 * @author shuo.cao
 * @Company: Autonavi
 * @date: 2011-5-12 下午05:49:43
 */
public abstract class MoveTemplate <T extends BatchPreparedStatementSetter>{
	
	protected static Log log = LogFactory.getLog(MoveTemplate.class) ;
	
	public static final String START_ROW_NUM = ":startRowNum" ;
	public static final String END_ROW_NUM = ":endRowNum" ;
	
	protected int batchSize = 30000 ;

	protected String countSql ;

	protected String insertSql ;
	
	protected String selectSql ;
	
	private void init(){
		this.setCountSql() ;
		this.setSelectSql() ;
		this.setInsertSql() ;
	}

	@SuppressWarnings("unchecked")
	public void move(JdbcTemplate from, JdbcTemplate to){
		
		Connection toc = null ;
		
		try{
			//初始化各参数
			this.init() ;
			
			toc = to.getDataSource().getConnection() ;
			
			//1、统计一共多少数据
			int countNum = from.queryForInt(this.getCountSql()) ;
			
			log.info("操作语句:"+this.getCountSql()) ;
			log.info("结果集总数为:"+countNum + " 条") ;
			
			int l = (countNum + this.getBatchSize() - 1) / this.getBatchSize() ;
			
			toc.setAutoCommit(false) ;
			
			for(int i=0; i<l; i++){
				
				int startRowNum = i * this.getBatchSize() ;
				int endRowNum = (i+1) * this.getBatchSize() ;
				if(i == l-1){
					endRowNum = countNum ;
				}
				
				//将变量转换为常量
				this.replaceVariable(startRowNum, endRowNum) ;
				
				List<Map<String, Object>> list = from.queryForList(this.getSelectSql()) ;
				
				log.info("第["+(i+1)+"]次获得结果集记录数:"+list.size() + " 条");
				
				int[] ns = to.batchUpdate(this.getInsertSql(), this.newBatchPreparedStatementSetter(list)) ;
				
				log.info("第["+(i+1)+"]次batch记录数:"+ns.length + " 条");
				
				toc.commit() ;
				
				log.info("第["+(i+1)+"]次插入数据为:" + (startRowNum+1) + "--"+endRowNum);
				
				//将常量换回变量,以便下一次循环使用
				this.replaceConstant(startRowNum, endRowNum) ;
				
				if(list.size() > 10000){
					
					Thread.sleep(5000) ;
				}
				
				log.info("第["+(i+1)+"]次循环结束!\n");
			}
			
			toc.setAutoCommit(true) ;
			
		}catch (Exception e) {
			
			//e.printStackTrace();
			log.info("【ERROR】数据迁移失败!原因如下:\n"+e.getMessage()) ;
			
			if(toc != null){
				try {
					toc.rollback() ;
				} catch (SQLException e1) {
					log.info("【ERROR】connection.rollback()失败!");
					e1.printStackTrace();
				}
			}
			
		} finally{
			if(toc != null){
				try {
					toc.close() ;
				} catch (SQLException e) {
					log.info("【ERROR】connection.close()失败!\n"+e.getMessage());
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 生成batchSetter对象
	 * @param list
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	@SuppressWarnings("unchecked")
	private final BatchPreparedStatementSetter newBatchPreparedStatementSetter(List<Map<String, Object>> list) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException{
		
		BatchPreparedStatementSetter setter = null ;
		Type t = this.getClass().getGenericSuperclass() ;
		
		if(t instanceof ParameterizedType){
			Type[] types = ((ParameterizedType)t).getActualTypeArguments() ;
			
			Constructor<T> constructor = ((Class<T>) types[0]).getConstructor(List.class) ;
			setter = constructor.newInstance(list) ;
		}
		
		return setter ;
	}

	/**
	 * 将变量替换为常量(即startRowNum和endRowNum的值)
	 * @param startRowNum
	 * @param endRowNum
	 * @return 替换后的查询语句
	 */
	private void replaceVariable(int startRowNum, int endRowNum){
		this.selectSql = this.getSelectSql().replace(MoveTemplate.START_ROW_NUM, startRowNum+"").replace(MoveTemplate.END_ROW_NUM, endRowNum+"");
	}
	
	private void replaceConstant(int startRowNum, int endRowNum){
		this.selectSql = this.getSelectSql().replace(endRowNum+"", MoveTemplate.END_ROW_NUM).replace(startRowNum+"", MoveTemplate.START_ROW_NUM) ;
	}
	
	/**
	 * scope is 1-30000
	 * @param batchSize
	 */
	protected final void setBatchSize(int batchSize) {
		if(batchSize > 0 && batchSize < 30001){
			this.batchSize = batchSize;
		}		
	}

	public abstract void setCountSql() ;
	/**
	 * 查询语句(下面是例子)
	 *	StringBuilder sql = new StringBuilder() ;
	 *	sql.append("select ID, X, Y, SPEED, HEIGHT, INPUTDATE, STATE from (") ;
	 *	sql.append("select rownum r, ID, X, Y, SPEED, HEIGHT, INPUTDATE, STATE from EP_LOCRECORD where rownum <= ") ;
	 *  sql.append(MoveData.END_ROW_NUM + " ") ;
	 *	sql.append("order by ID asc) ") ;
	 *	sql.append("where r > ") ;
	 *	sql.append(MoveData.START_ROW_NUM) ;
	 * @param selectSql
	 */
	protected abstract void setSelectSql() ;
	/**
	 * insert语句要和select语句对应
	 * @param insertSql
	 */
	public abstract void setInsertSql() ;
	
	protected int getBatchSize() {
		return batchSize;
	}
	
	private String getCountSql() {
		return countSql;
	}
	
	private String getInsertSql() {
		return insertSql;
	}
	
	private String getSelectSql() {
		return selectSql;
	}
	
}

2011年5月16日 15:38
0 0

楼主,如果2000万数据insert到另一个表里面,日志空间的管理十分重要,你所说的“ 当执行到第10万条左右时,效率非常低... ”很有可能是因为日志空间不足或是表的锁机制不合理造成的。
有两个办法解决这个效率问题:
1:将C表上的index全部drop掉再做insert,完成insert后重建index.
2:使用sql server的bcp工具.
我个人推荐使用bcp工具,速度快,且不写日志空间.

2011年5月10日 11:27
0 0

引用
insert into c select * from a SQL语句可以这样写吗?


可以,但是列名必须得匹配。

2011年5月09日 11:01
0 0

insert into c select * from a SQL语句可以这样写吗?

2011年5月09日 09:54
0 0

isB2是什么意思,是说在a1=B1同时a2=b2吗?还是说B表存在一行b2的值等于a2?

如果只是判断a1在B表中的存在性还好说,同时加上a2的存在性,那效率确实很难提高。

先说说只判断a1的存在性的解决:

事先建好c表, 不带索引和主键

insert into c select a.a1,a.a2,a.a3, 1, 0 from A a where a.a1 in (select b1 from B)

insert into c select a.a1,a.a2,a.a3, 0, 0 from A a where a.a1 not in (select b1 from B)

至于isB2字段的值, 你得通过程序来更新了。

2011年5月09日 09:32
0 0

insert into c select * from a;--先复制A表.
alter table c add isb1 smallint,isb2 smallint;---添加两个新加的字段.
create index on c(a1)--a1创建索引...a1=B的主键,选择性是否好?(重复的数据是否多).
循环b表数据,根据相应的条件更新isb1,isb2列.(cursor循环).
cursor is select b1,b2 from b
--loop

2011年5月08日 22:32
0 0

1.分批添加,每批差不多10万条
2.把索引,约束都先停用,等都复制完了再添加上去

2011年5月08日 22:25

相关推荐

    Excel数据导入到SQLServer数据库中

    本文将详细讲解如何将Excel数据导入到SQL Server数据库中,并探讨这个过程中的关键知识点。 首先,导入Excel数据到SQL Server通常有几种方法:使用SQL Server Management Studio (SSMS) 的“导入和导出数据”向导、...

    SQL Server数据库查询速度慢原因及优化方法

    【赛迪网-IT技术报道】SQL Server数据库查询速度慢的原因有很多,常见的有以下几种:  1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)  2、I/O吞吐量小,形成了瓶颈效应。  3、没有...

    从sqlserver数据库到MYSQL数据库转换操作指南

    从 SQL Server 数据库到 MySQL 数据库转换操作指南 在实际开发和数据分析中,数据库的选择和转换是非常常见的操作。随着业务的发展和技术的演进,数据库的选择和转换也变得越来越复杂。因此,本文将指导您从 SQL ...

    下载SqlServer数据库表格好内容到sqlite数据库工具

    本话题聚焦于如何将SqlServer数据库中的表内容高效地下载并导入到sqlite数据库中。所提及的工具——SqlConverter_v1_20,是一个专门为此目的设计的应用程序,它简化了两个不同数据库系统之间的数据同步过程。 首先...

    SQLServer利用SSIS包定时同步新增数据到其它库

    本文主要介绍如何使用 SSIS 包定时同步 SQL Server 中的数据到其他数据库,特别针对新增数据的同步。 #### 二、基础知识 在深入了解具体操作之前,我们需要了解以下几个基础概念: - **SSIS (SQL Server ...

    labview写入数据到sql server2005

    在“labview写入数据到sql server2005”的场景中,LabVIEW被用来作为数据处理和控制工具,与SQL Server 2005数据库进行交互,实现数据的写入操作。SQL Server 2005是微软公司的关系型数据库管理系统,它提供了数据...

    VBA连接SQLSERVER数据库实例.doc

    在本文中,我们将深入探讨如何使用VBA(Visual Basic for Applications)通过ADO(ActiveX Data Objects)连接到SQL Server数据库并执行数据查询。这个过程在Excel中尤其常见,因为VBA是Excel内置的编程环境,允许...

    在SQL Server数据库之间进行数据导入导出

    在SQL Server数据库之间进行数据导入导出是数据库管理中常见的操作,主要目的是为了数据备份、迁移、合并或者处理跨数据库的数据需求。以下详细介绍几种常用的方法。 1. **使用SELECT INTO导出数据** SELECT INTO...

    sql server数据库教程详解

    在 SQL Server 中,数据访问主要通过以下几种方式实现: - **DataProvider(数据提供程序)**:这是用于访问数据源的一组组件。主要包括连接、命令、数据适配器等。 - **DataSet**:这是一个内存中的缓存,用于存储...

    图片存到SQL Server数据库中

    实现图片存储到SQL Server数据库中的过程可以分为以下几个步骤: 1. **创建数据库表**:首先需要在SQL Server中创建一个包含`image`或`varbinary(max)`类型的字段来存放图片数据的表。例如,以MS自带的数据库...

    图片存储到SQLServer数据库中

    本主题聚焦于如何将图片存储到SQL Server数据库中,主要涉及Java编程语言进行数据库开发的相关知识。 首先,我们有几种常见的图片存储方式: 1. **BLOB(Binary Large Object)存储**:这是最直接的方法,图片以二...

    ACCESS 与SQL SERVER数据库数据相互转换,ACCESS,SQL SERVER

    本篇将详细探讨ACCESS与SQL Server数据库之间的数据转换方法,以及它们各自的特点。 ACCESS是一款轻量级、易于使用的数据库管理系统,主要面向个人用户或小型团队,适合于简单的数据管理任务。它基于Jet引擎,提供...

    sqlserver数据库对比工具

    描述中提到的"SQLSERVER数据库对比工具.exe"很可能是一个专门设计用于对比SQL Server数据库的应用程序。它可能具备以下功能: 1. **对比表结构**:检查两个数据库中的表是否有不同的字段、数据类型、索引或约束。 2...

    SQLSERVER数据库性能优化分析

    ### SQLSERVER数据库性能优化分析 #### 一、问题分析 **1.1 死锁** 在SQL Server数据库中,死锁是一种常见的性能问题。当多个事务互相等待对方释放资源时,就会形成死锁。例如,进程A锁定了资源B,进程B锁定了...

    SQL Server数据库的性能分析和优化策略研究

    综上所述,SQL Server数据库的性能优化是一个综合性的过程,涉及到逻辑数据库设计、物理数据库生成策略以及查询优化等多个方面。通过合理的数据库设计、高效的物理资源配置以及精细的查询优化,可以显著提高SQL ...

    null关系型数据库及SQL语句,SQLSERVER数据库设计.doc

    SQLSERVER数据库设计的实现方法可以分为以下几个步骤: * 创建数据库:使用CREATE DATABASE语句创建数据库 * 创建表:使用CREATE TABLE语句创建表 * 创建视图:使用CREATE VIEW语句创建视图 * 创建索引:使用CREATE...

    50种方法巧妙优化你的SQL Server数据库

    1. **建立和优化索引**:索引是加速查询的关键,特别是在大数据量的表中。合理创建主键、唯一键和非聚集索引,避免全表扫描。对于像`LIKE '%a%'`这样的模糊查询,普通索引可能无效,此时可以考虑使用全文索引。 2. ...

    数据库sqlserver攻关

    SELECT INTO FROM则用于从一个或多个表中选择数据,并创建一个新表来存储这些数据。 ### Set和Select赋值区别 SET用于为变量赋值,而SELECT用于从结果集中选择数据。在SQL Server中,通常使用SET给局部变量赋值,...

    Sql Server 2000 数据迁移至Oracle(含NClOB特殊字段)

    数据迁移是指将数据从一个系统转移到另一个系统的流程。在本案例中,涉及的是从Sql Server 2000迁移至Oracle数据库的过程,并且特别提到了包含NCLOB特殊字段的情况。NCLOB(National Character Large Object Binary...

    Excel把数据导入到SQL数据库中

    2. 创建 SQL 数据库:在 SQL Server 中创建一个新的数据库,以便存储从 Excel 中导入的数据。 3. 安装 Excel 数据连接驱动程序:需要安装 Excel 数据连接驱动程序,以便将 Excel 数据导入到 SQL 数据库中。 二、...

Global site tag (gtag.js) - Google Analytics