insert与索引的互影响

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了insert与索引的互影响相关的知识,希望对你有一定的参考价值。

请问INSERT操作对于有索引和无索引的表在速度上都是相同的吧?也就是说索引对于INSERT操作没有影响,但UPDATE操作会有影响,尤其是UPDATE索引字段的情况还有WHERE中带有索引字段的情况?谢谢!

参考技术A 存在索引的表,INSERT操作会更慢。
假设插入1000W条数据,如果没有索引,可能只需要生成1G的空间,如果有了索引,那么可能额外再生成0.5G的索引数据,同时oracle服务器还要计算这些索引,因此,如果表存在索引,插入数据时,受CPU计算索引数据及硬盘写入索引数据的影响,会更慢。

全表update也会存在这个问题,但如果只是update部分数据,并且where条件合理的引用索引,那么oracle找出这部分需要更新数据的时间更短了,也就是查询更快,最终update耗时反而会更短。本回答被提问者和网友采纳

SQL语法:Replace into 与 Insert into 的区别

replace into 和insert into都是基于唯一索引或主键基础上使用的,必须有主键或唯一索引。假如表中的一个旧记录与一个用于primary key或一个unique索引的新记录具有相同的值,则在新记录被插入之前,旧记录被删除。注意:除非表有一个primary key或unique索引,否则,使用一个replace语句没有意义。该语句会与insert相同,因为没有索引被用于确定是否新行复制了其它的行。

首先创建一张test表:

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` bigint(20) NOT NULL COMMENT '主键ID',
  `name` varchar(50) DEFAULT NULL,
  `phone` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试表';

执行单条语句测试:

--执行单条数据的insert into
[SQL]INSERT INTO test (id, NAME, phone) VALUES('1', 'Alice', '123456789');
受影响的行: 1
时间: 0.024s
 
--执行单条数据的replace into
[SQL]REPLACE INTO test (id, NAME, phone) VALUES('2', 'Bob', '123456788');
受影响的行: 1
时间: 0.023s

由上可见,当主键和唯一索引 ‘id’ 列不重复,两者执行时间及影响行数(插入的方式)基本等同。

--再来看看主键重复的情况 
--1、执行insert into
[SQL]INSERT INTO test (id, NAME, phone) VALUES('2', 'Tom', '123456789');
[Err] 1062 - Duplicate entry '2' for key 'PRIMARY'
 
--2、执行replace into
[SQL]REPLACE INTO test (id, NAME, phone) VALUES('2', 'Jerry', '123456788');
受影响的行: 2
时间: 0.026s

replace语句会返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和。如果对于一个单行replace该数为1,则一行被插入,同时没有行被删除。如果该数大于1,则在新行被插入前,有一个或多个旧行被删除。如果表包含多个唯一索引,并且新行复制了在不同的唯一索引中 的不同旧行的值,则有可能是一个单一行替换了多个旧行。受影响的行数可以容易地确定是否replace只添加了一行,或者是否replace也替换了其它行:检查该数是否为1(添加)或更大(替换)。
可以看到insert into是不允许添加主键重复列的,而replace into可以,且影响行数是2。replace into用于不知道操作为更新还是新增的时候,使用时,先尝试直接向库中插入数据,遇到主键或唯一索引而引发的重复键错误时,删除掉冲突行并再次尝试插入,这个过程是数据库自行处理的,并不会存在用户感知之类的。

再说下 replace into 的三种使用形式:

  1. replace into test(id,name …) values(…)

  2. replace into test(id,name, …) select …

  3. replace into test set id=value, name=value,…

第一种形式类似于insert into的用法。
第二种replace select的用法也类似于insert select,这种用法并不一定要求列名匹配,事实上,SQL甚至不关心select返回的列名,它需要的是列的位置。例如,replace into test1 ( id, name, phone) select id, name, address from test2;这个例子使用replace into从test2中将所有数据导入test1中。
第三种replace set用法类似于update set用法,使用一个例如“SET col_name = col_name + 1”的赋值,则对位于右侧的列名称的引用会被作为DEFAULT(col_name)处理。因此,该赋值相当于SET col_name = DEFAULT(col_name) + 1。
前两种形式用的多些。其中 “into” 关键字可以省略,不过最好加上 “into”,这样意思更加直观。另外,对于那些没有给予值的列,SQL 将自动为这些列赋上默认值。

以上是关于insert与索引的互影响的主要内容,如果未能解决你的问题,请参考以下文章

请教高手oracle 创建了索引后在使用SELECT,UPDATE,DELETE和INSERT语句时性能影响上有啥不同?

SQL Server 中的表统计信息会影响 INSERT、UPDATE 性能吗?

sql server insert 与 delete 三百万级数据量时速度极慢,有10分钟左右,求高手如何解决

delete-insert 与 if-update else-insert 的最佳选择是哪个?

InnoDB,select为啥会阻塞insert?

SQL语法:Replace into 与 Insert into 的区别