insert into linksvr or insert into from linksvr
通过链接服务器将实例A上的数据写入实例B,通常有以下两种方式
--方案1:在实例A上执行
insert into LinkForB.B..TableB select * from TableA
--方案2:在实例B上执行
insert into TableB select * from LinkForA.A..TableA
目前接手的数据库,大量使用链接服务器来搬迁数据,并且使用者随心所欲。本地写入到链接服务器,从链接服务器读数据写入本地,从链接服务器读数据写入到另一链接服务器。更有坑爹的,本来是写入本地,却在本地的前面加上本地实例的链接服务器!
--20160519
问个问题,实例A上的作业通过链接服务器从实例B获取数据然后写入到实例C,三个实例在不同的服务器。这个实例A充当的是什么角色,它和直接实例B"推"数据给实例C,或者实例C从实例B"拉"数据有什么区别,优劣势如何?
--20160629
Q:三台数据库服务器A、B、C,大致的定位是A写入、B读取、C归档。所有新数据写入到A;页面查询、统计作业放在B。目前A到B,B到C是在作业中通过链接服务器insert...select from linksvr的方式。然后会定期删除A、B中的历史数据。感觉这种方式不稳定,而且如果表的个数很多,通过链接服务器也不方便。大家有没有什么建议?
A:1、使用复制,A复制到B和C;2、AlwaysOn;3、定时跑存储过程,将要插入的语句和删除的语句放在存储过程里面。你把插入的语句放在它本机,通过链接服务器去查询。
以前没有特别关注哪种方式更好,有在群里针对搬迁数据的方式请教过,有朋友建议最好采用pull的链接方式,即insert into TableB select * from LinkForA.A..TableA
偶然看到园子里的文章(为什么透过链接服务器写入,速度会很慢),结合自己遇到的问题,尝试分析通过链接服务器insert数据的区别。
此处为了方便,我所创建的链接服务器[MY]实际是指向当前实例,但是不影响对结果的分析。
首先创建测试表,并在测试表上创建触发器
USE TEST
GO
--脚本参考http://www.cnblogs.com/wanyong117/p/5764644.html修改
--创建测试表
CREATE TABLE [dbo].[Product](
[ProductID] INT,
[Name] [nvarchar](50),
[Remark] [nvarchar](50)
)
GO
--创建触发器
CREATE TRIGGER [dbo].[Product_TR]
ON [dbo]. [Product]
FOR INSERT
AS
BEGIN
SET XACT_ABORT ON
BEGIN TRY
IF (select len(ProductID) from inserted)>0--当select查询只返回一个值时才能操作=、!=、<、<=、>、>=
BEGIN
PRINT 'one row'
END
END TRY
BEGIN CATCH
PRINT '消息 '+CONVERT(VARCHAR,ERROR_NUMBER())+',级别 '+CONVERT(VARCHAR,ERROR_SEVERITY())
+',状态 '+CONVERT(VARCHAR,ERROR_STATE())+',过程 '+CONVERT(VARCHAR,ERROR_PROCEDURE())
+',第 '+CONVERT(VARCHAR,ERROR_LINE())+' 行'
PRINT ERROR_MESSAGE()
END CATCH
END
GO
注意触发器脚本,是为了在批量插入数据,select...from inserted子查询返回多条记录,进行>操作出错。
插入数据检验
--Step1:插入1条数据,成功
INSERT [Test].[dbo].[Product]( [ProductID],[Name],[Remark])
SELECT TOP 1 [ProductID],[Name],'one row'
FROM [AdventureWorks2008R2].[Production].[Product]
--Step2:插入5条数据,失败
INSERT [Test].[dbo].[Product]( [ProductID],[Name],[Remark])
SELECT TOP 5 [ProductID],[Name],'more than one row'
FROM [AdventureWorks2008R2].[Production].[Product]
--Step3:插入5条数据到链接服务器,成功
INSERT [MY].[Test].[dbo].[Product]([ProductID],[Name],[Remark])
SELECT TOP 5 [ProductID],[Name],'ToLink more than one row'
FROM [AdventureWorks2008R2].[Production].[Product]
--Step4:从链接服务器获取5条数据再插入,失败
INSERT [Test].[dbo].[Product]( [ProductID],[Name],[Remark])
SELECT TOP 5 [ProductID],[Name],'FromLink more than one row'
FROM [MY].[AdventureWorks2008R2].[Production].[Product]
Step2和Step4的错误信息如下
我们查看表中数据
通过图中的Remark字段,可以看出Step1和Step3的语句执行成功,Step2和Step4的语句执行失败
Step1:插入1条数据时,select...from inserted子查询返回1行值,它可和0进行比较(>),数据insert成功。
Step2:插入5条数据时,select...from inserted子查询返回5行值,它不能和单一的0进行比较,触发器报错,整个insert语句失败。
Step3:插入5条数据到链接服务器,竟然成功!对比前面的语句,说明insert into linksvr.db.sch.tb是一行一行的insert(因为表上有触发器,如果一次多行insert会报错)
Step4:当从链接服务器获取5条数据,再insert失败!它近似等效于Step2。
现在我们的问题是Step3和Step4到底哪个更高效?虽然此时我们已经知道,Step3会拆分成单条写入,Step4一次写入多条。为了让这两个语句正常执行,我们禁用表上的触发器
--禁用/启用触发器
alter table [dbo].[Product]
disable trigger [Product_TR] --disable/enable
--查看触发器
select name,type_desc,create_date,modify_date,is_disabled from sys.triggers t
开启跟踪,然后再次执行Step3、Step4中的语句
INSERT [MY].[Test].[dbo].[Product]([ProductID],[Name],[Remark])
SELECT TOP 5 [ProductID],[Name],'ToLink more than one row'
FROM [AdventureWorks2008R2].[Production].[Product]
在SPID=52窗口执行INSERT Linksvr SELECT TOP 5 FROM语句,链接服务器在SPID=55下执行,有5个RPC:Completed事件
INSERT [Test].[dbo].[Product]( [ProductID],[Name],[Remark])
SELECT TOP 5 [ProductID],[Name],'FromLink more than one row'
FROM [MY].[AdventureWorks2008R2].[Production].[Product]
在SPID=52窗口执行INSERT Tab SELECT TOP 5 FROM Linksvr语句,链接服务器在SPID=55的会话中执行,仅一个RPC:Completed事件
此时表中的数据如下
如果将表中数据全部写入到测试表,跟踪添加筛选器SPID=52
Duration字段可以看出insert linksvr要比insert select linksvr耗时些。其实就是要存一万块钱,是每次只存一百(需100次),还是每次存一万(需1次)。显然后者更高效。
--删除测试表
USE TEST
GO
DROP TABLE [TEST].[dbo].[Product]
insert into linksvr or insert into from linksvr的更多相关文章
- 使用batch insert解决MySQL的insert吞吐量问题
最近使用了一个非常简单易用的方法解决了业务上的一个insert吞吐量的问题,在此总结一下. 首先我们明确一下,insert吞吐量其实并不是指的IPS(insert per second),而是指的RP ...
- mysql 数据库插入语句之insert into,replace into ,insert ignore
近期才发现mysql的插入语句竟然有如此多的使用方法,这里拿来分享一下. ①关于insert into : insert into table_name values(); insert into t ...
- Sqlite执行insert or ignore 或insert or replace语句。
Sqlite执行insert or ignore 或insert or replace语句. ,); ,); 上面的第一条语句是每次执行时,如果不存在,则添加,如果存在,则更新. 上面的第二条语句是每 ...
- Hive:insert into table 与 insert overwrite table 区别
创建测试表,来测试看看测试结果: create table test(name string,pwd string,createdate string)row format delimited fie ...
- sqlite "insert or replace" 和 "insert or ignore" 用法
insert or replace:如果不存在就插入,存在就更新insert or ignore:如果不存在就插入,存在就忽略只对UNIQUE约束的字段起作用.举例:建表:CREATE TABLE T ...
- oracle 中 insert select 和 select insert 配合使用
Insert Into select 与 Select Into 哪个更快? 在平常数据库操作的时候,我们有时候会遇到表之间数据复制的情况,可能会用到INSERT INTO SELECT 或者 SEL ...
- SQL Server 动态生成数据库所有表Insert语句
一. 背景 SQL Server,如果我们需要把数据库A的所有表数据到数据库B中,通常我们会怎么做呢?我会使用SSMS的导入导出功能,进行表数据的导入导出,无可厚非,这样的导入非常简单和方便: 但是, ...
- MyBatis魔法堂:Insert操作详解(返回主键、批量插入)
一.前言 数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二. insert元素 属性详解 其属性如下: parameterType ...
- oracle中 SELECT INTO 和INSERT INTO ... SELECT区别
在Oracle中,将一张表的数据复制到另外一个对象中.通常会有这两种方法:insert into select 和 select into from. 前者可以将select 出来的N行(0到任意数 ...
随机推荐
- 【Java EE 学习 25 上】【网上图书商城项目实战】
一.概述 1.使用的jdk版本:1.6 2.java EE版本:1.6 3.指导老师:传智播客 王建 二.小项目已经实现的功能 普通用户: 1.登陆 2.注册 3.购物 4.浏览 管理员用户(全部管理 ...
- PAT A 1115. Counting Nodes in a BST (30)【二叉排序树】
题目:二叉排序树,统计最后两层节点个数 思路:数组格式存储,insert建树,dfs遍历 #include<cstdio> #include<iostream> #includ ...
- Linux第03天
Linux 第03天 1.Linux帐号和ACL权限管理 1.帐号和用户组 1.1 用户标识符————UID(root为0 系统用户为1~499 普通用户为500~65535) 1.2 用户组标识符— ...
- 验证启用了不安全的HTTP方法
安全风险: 可能会在Web 服务器上上载.修改或删除Web 页面.脚本和文件. 可能原因: Web 服务器或应用程序服务器是以不安全的方式配置的. 修订建议: 如果 ...
- jsp 中登录验证 注销 的模版
用户名密码验证模版 <%@page import="com.jerehedu.bao.User"%> <%@ page language="ja ...
- 归一化交叉相关Normalization cross correlation (NCC)
归一化交叉相关Normalization cross correlation (NCC) 相关系数,图像匹配 NCC正如其名字,是用来描述两个目标的相关程度的,也就是说可以用来刻画目标间的相似性.一般 ...
- Leetcode Reverse Nodes in k-Group
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...
- STM32之GPIO操作
啊哈.没办法.外国人的芯片就喜欢用英文来命名,所以中文的:通用输入/输出 就用GPIO来代替..谁叫哥们都不是外国人呢.好啦.胡扯了一下,借用唐伯虎点秋香的话:小小书童,可笑可笑... 知道了GPI ...
- *HDU1142 最短路+记忆化dfs
A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
- 常用Oracle函数记录
1. Oracle的replace函数与translate函数 replace函数是在字符串级别的代替,对应字符串一一替换 SQL> SELECT REPLACE('accd','cd','ef ...