-
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个答案 按时间排序 按投票排序
-
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
-
这是一个子类的实现:
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
-
介绍下我的解决办法:
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
-
楼主,如果2000万数据insert到另一个表里面,日志空间的管理十分重要,你所说的“ 当执行到第10万条左右时,效率非常低... ”很有可能是因为日志空间不足或是表的锁机制不合理造成的。
有两个办法解决这个效率问题:
1:将C表上的index全部drop掉再做insert,完成insert后重建index.
2:使用sql server的bcp工具.
我个人推荐使用bcp工具,速度快,且不写日志空间.2011年5月10日 11:27
-
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
-
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
--loop2011年5月08日 22:32
相关推荐
本文将详细讲解如何将Excel数据导入到SQL Server数据库中,并探讨这个过程中的关键知识点。 首先,导入Excel数据到SQL Server通常有几种方法:使用SQL Server Management Studio (SSMS) 的“导入和导出数据”向导、...
【赛迪网-IT技术报道】SQL Server数据库查询速度慢的原因有很多,常见的有以下几种: 1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2、I/O吞吐量小,形成了瓶颈效应。 3、没有...
从 SQL Server 数据库到 MySQL 数据库转换操作指南 在实际开发和数据分析中,数据库的选择和转换是非常常见的操作。随着业务的发展和技术的演进,数据库的选择和转换也变得越来越复杂。因此,本文将指导您从 SQL ...
本话题聚焦于如何将SqlServer数据库中的表内容高效地下载并导入到sqlite数据库中。所提及的工具——SqlConverter_v1_20,是一个专门为此目的设计的应用程序,它简化了两个不同数据库系统之间的数据同步过程。 首先...
本文主要介绍如何使用 SSIS 包定时同步 SQL Server 中的数据到其他数据库,特别针对新增数据的同步。 #### 二、基础知识 在深入了解具体操作之前,我们需要了解以下几个基础概念: - **SSIS (SQL Server ...
在“labview写入数据到sql server2005”的场景中,LabVIEW被用来作为数据处理和控制工具,与SQL Server 2005数据库进行交互,实现数据的写入操作。SQL Server 2005是微软公司的关系型数据库管理系统,它提供了数据...
在本文中,我们将深入探讨如何使用VBA(Visual Basic for Applications)通过ADO(ActiveX Data Objects)连接到SQL Server数据库并执行数据查询。这个过程在Excel中尤其常见,因为VBA是Excel内置的编程环境,允许...
在SQL Server数据库之间进行数据导入导出是数据库管理中常见的操作,主要目的是为了数据备份、迁移、合并或者处理跨数据库的数据需求。以下详细介绍几种常用的方法。 1. **使用SELECT INTO导出数据** SELECT INTO...
在 SQL Server 中,数据访问主要通过以下几种方式实现: - **DataProvider(数据提供程序)**:这是用于访问数据源的一组组件。主要包括连接、命令、数据适配器等。 - **DataSet**:这是一个内存中的缓存,用于存储...
实现图片存储到SQL Server数据库中的过程可以分为以下几个步骤: 1. **创建数据库表**:首先需要在SQL Server中创建一个包含`image`或`varbinary(max)`类型的字段来存放图片数据的表。例如,以MS自带的数据库...
本主题聚焦于如何将图片存储到SQL Server数据库中,主要涉及Java编程语言进行数据库开发的相关知识。 首先,我们有几种常见的图片存储方式: 1. **BLOB(Binary Large Object)存储**:这是最直接的方法,图片以二...
本篇将详细探讨ACCESS与SQL Server数据库之间的数据转换方法,以及它们各自的特点。 ACCESS是一款轻量级、易于使用的数据库管理系统,主要面向个人用户或小型团队,适合于简单的数据管理任务。它基于Jet引擎,提供...
描述中提到的"SQLSERVER数据库对比工具.exe"很可能是一个专门设计用于对比SQL Server数据库的应用程序。它可能具备以下功能: 1. **对比表结构**:检查两个数据库中的表是否有不同的字段、数据类型、索引或约束。 2...
### SQLSERVER数据库性能优化分析 #### 一、问题分析 **1.1 死锁** 在SQL Server数据库中,死锁是一种常见的性能问题。当多个事务互相等待对方释放资源时,就会形成死锁。例如,进程A锁定了资源B,进程B锁定了...
综上所述,SQL Server数据库的性能优化是一个综合性的过程,涉及到逻辑数据库设计、物理数据库生成策略以及查询优化等多个方面。通过合理的数据库设计、高效的物理资源配置以及精细的查询优化,可以显著提高SQL ...
SQLSERVER数据库设计的实现方法可以分为以下几个步骤: * 创建数据库:使用CREATE DATABASE语句创建数据库 * 创建表:使用CREATE TABLE语句创建表 * 创建视图:使用CREATE VIEW语句创建视图 * 创建索引:使用CREATE...
1. **建立和优化索引**:索引是加速查询的关键,特别是在大数据量的表中。合理创建主键、唯一键和非聚集索引,避免全表扫描。对于像`LIKE '%a%'`这样的模糊查询,普通索引可能无效,此时可以考虑使用全文索引。 2. ...
SELECT INTO FROM则用于从一个或多个表中选择数据,并创建一个新表来存储这些数据。 ### Set和Select赋值区别 SET用于为变量赋值,而SELECT用于从结果集中选择数据。在SQL Server中,通常使用SET给局部变量赋值,...
数据迁移是指将数据从一个系统转移到另一个系统的流程。在本案例中,涉及的是从Sql Server 2000迁移至Oracle数据库的过程,并且特别提到了包含NCLOB特殊字段的情况。NCLOB(National Character Large Object Binary...
2. 创建 SQL 数据库:在 SQL Server 中创建一个新的数据库,以便存储从 Excel 中导入的数据。 3. 安装 Excel 数据连接驱动程序:需要安装 Excel 数据连接驱动程序,以便将 Excel 数据导入到 SQL 数据库中。 二、...