Oracle中需要动动脑袋的sql问题

据库三范式

了解数据库三范式
范式主要用于消除数据库中的冗余数据,改进数据库整体组织,增强数据的一致性,增加数据库设计的灵活性。

第一范式1NF:

第一范式要求
两个含义重复的字段不能在同一个表中
一个表中的一列不能是其他列的计算结果
一个表中的一列取值不能有多个含义
如下图违反第一范式
在这里插入图片描述
应改成
在这里插入图片描述
因为会导致后期查询like %电话%,查询导致索引失效

第二范式2NF:

首先要满足第一范式,第二范式是在第一范式的基础上建立起来的,第二范式就是非主键列属性都要依赖于主键列上的属性;
如下图两个表银行表bank和账户表account,两者为一对多关系即一个银行包含多个账户,一个账户只属于一个银行,银行位置字段BankLocation不应该在账户表ACCOUNT中,应该在Bank表中,违反第二范式;
在这里插入图片描述

第三范式3NF:

要满足第二范式,如果数据库表中不存在非关系列(非主键列)对任一主键的传递函数依赖,则符合第三范式;所谓传递函数依赖,指的是如果存在A-B-C的决定关系,则C传递函数依赖于A;
如学号-联系方式-联系电话、家庭住址,如果这些字段出现在一个表中即不符合第三范式,应拆成两个表,如下图:
在这里插入图片描述

序列

序列使用场景

序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字),一般流水号需求使用序列做,如果一个部门用一种流水号不适合有序列做,因为部门可以随时添加删除;

序列的使用

--创建序列
create sequence test_sequence
--最小值
minvalue 1
--最大值
maxvalue 9999999999999999
--起始值
start with 1
--自增值
increment by 1
--高速缓存值(cache 值为20,如果currval值为2,当数据库挂了重启再次数据库会将cache值设置给currval值,数据库序列值会跳)
cache 20;

--序列值+1,返回序列值
select test_sequence.nextval from dual
--获得序列当前位置
select test_sequence.currval from dual

--删除序列
drop sequence test_sequence
--查询所有没有包的序列信息 此处的last_num是每次已经缓存了多少值
select max_value,last_number from USER_SEQUENCES where sequence_name ='TEST_SEQUENCE'
--修改序列高速缓存大小(在下一次被nextval时进行缓存刷新)
ALTER SEQUENCE test_sequence CACHE 1000

索引

索引是什么
索引(index):索引是数据库的一种对象,索引的作用是提高根据索引列的查询效率
索引与表中数据的关系就像书的目录与书中内容之间的关系
索引特点
建立索引是耗时的,因为数据库会刚根据索引列的值,计算生成一棵索引树
索引需要存储空间,因为需要系统产生对应的索引表来存放该索引产生的索引树信息
索引对于DML(insert ,delete,update)语句的影响:
在表上建立索引,提供了根据索引列的查询效率的同时,会降低该改变进行DML操作的效率。
索引建立的基本原则:
1、只在经常作为查询条件的列上建立索引
2、在数据量大(10w条以上)的表上建立索引
不适合建立索引的情况(建立索引也看不到效果):
1、数据量比较小
2、存在大量重复信息的列不适合做索引
3、不要在经常进行DML操作的表上建立索引
索引建立的时机:
在系统使用频率最低的时候创建索引
索引和主键的关系:
主键是约束的一种:主键约束的列必须保证非空而且唯一。在数据库中当创建唯一约束时,会自动创建一个索引,根据主键列查询可以提高查询效率

分区
当数据量特别大的时候,我们可以建立分区表.再建立索引
分区表是指在建立表的时候就定义好分区原则,当插入数据时,将根据分区条件进行分区。
如果将索引比喻成书的目录,那么分区就好比先对图书进行分册

索引什么时候创建和失效

--1、没有根据索引列查询索引不起作用
select * from db_big where bignum=100
--2、在索引字段上进行函数运算索引失效(只有当索引列作为查询条件才好使)
select * from db_big where substr(bigname,1,20)='8A95E997857A4902AB55'
  --补充,如果一定要用函数请根据函数建立索引
  create index index_substr on db_big(substr(bigname,1,20))
--3、当在索引列上进行模糊查询时,%或_前置时失效(因为无法开始索引树的查找)
select * from db_big where bigname like '_A95E997857A4902AB55'
--4、如果根据to_date或者to_char函数建立索引,在查询时关于格式的大小写与建立索引时不一致则会导致索引失效
create index index_big_date on db_big(to_char(bigdate,'yyyy-mm-dd'))
select * from db_big where to_char(bigdate,'YYYY-mm-dd')='1983-02-05'
--5、如果索引列上存在null值则对null值进行查询失效(因为null值不会放入索引树中)
select * from db_big where bigname is null
--补充:经常作为查询条件的字段可以建立联合索引(减少对DML的影响和减少对数据库硬盘空间的占用)
drop index INDEX_BIG_NAME
--6、如果单独查询联合索引中第二个字段则索引失效(找不到索引树的根)
create index  index_big_name_num on db_big(bigname,bignum)
使用bigname单独进行查询不失效   使用bignum进行查询失效   因为bigname和bignum建立的索引是由顺寻的和bigname再前面 bignum再后面形成的索引
--7、联合索引如果进行 or(即或组合)则失效
--除非要在所有要查询的列上创建索引才能生效
select * from db_big where   bigname='A78F978CD00C401A9C67'  or bignum=100
--8、如果查询有运算则索引失效
select * from db_big where column= column+1
--9、不使用NOT IN和<>操作
--10、要限制索引数目,索引的数目不是越多越好。每个索引都是要占用磁盘空间的,索引越多,需要的磁盘空间就越大。修改表时,和更新会很麻烦。越多的索引,会使更新表变得很浪费时间
--11、列上面存储的输入如果不复杂不适合创建索引,比如一列只存男或者女索引使用
--12、索引和表所在的表空间要尽量不同
--13、创建复合索引后,create index in_test1 on test (a,b,c) 索引顺序要从abc三列的字段存储数据的复杂程度排序,在查询时候根据顺序使用and进行查询,如果只通过c字段进行查询起不到索引的作用;
--14索引中不要使用not,not 不会使用索引使用 <>

索引操作

--创建
create index index_test_nba_uname on test_nba(uname);
--删除
drop index index_test_nba_uname;
--重建
alter index index_test_nba_uname rebuild online;
--系统视图存放是索引的名称以及该索引是否是唯一索引等信息,
select index_name from dba_indexes  where table_name =UPPER('ReportLog')
--统视图存放的是索引名称,对应的表和列等
select * from dba_ind_columns  where index_name in (select index_name from dba_indexes  where table_name =UPPER('ReportLog'))

索引测试

数据生成准备 了解oracle程序代码块

declare
  --声明变量
  v_num number(1);
  v_sex char(2);
begin 
  --得到[0,1]随机数
  select floor(dbms_random.value(0,2)) into v_num from dual;
  --根据v_num的值判断男女
  if v_num=0 then
     v_sex := '男';  --给变量赋值
  else
     v_sex :='女';
  end if;
  dbms_output.put_line(v_sex);
end ;

数据准备

create table db_big
(
       bigid varchar2(32),
       bigname varchar2(20),
       bigdate date,
       bigsex char(2),
       bignum number(7)
)
--别建主键
insert into db_big(bigid,bigname,bigdate,bigsex,bignum)
values(sys_guid(),)
--随机20位码
select substr('abcde',2,2) from dual--substr(字符串,开始位置,截取几个)
select substr(sys_guid(),1,20) from dual
--随机时间
select sysdate-70 from dual;
   --得到随机整数数
   select floor(dbms_random.value(10,50)) from dual
   --时间截取
   select trunc(sysdate) from dual --对时间进行截取(默认省略时分秒)
   --随机时期
    select trunc(sysdate)+floor(dbms_random.value(-50000,50000)) from dual 
--随机性别
    --得到[0,1]的随机整数
    select floor(dbms_random.value(0,2)) from dual
    --如果是0则表示为男1则表示为女

200万数据生成

declare
  --声明如下变量
  v_bigname varchar2(20);
  v_bigdate date;
  v_num  number(7);
  v_sex  char(2);
begin
  for i in 1..2000000    --循环10次
  loop
     --得到随机v_bigname
     select substr(sys_guid(),1,20) into v_bigname from dual;
     --得到随机时间
     select (trunc(sysdate) + floor(dbms_random.value(-30000,30000))) into v_bigdate from dual;
     --得到随机性别
     if  floor(dbms_random.value(0,2)) = 0 then 
         v_sex:='男';
     else
         v_sex:='女';
     end if;
     --得到随机数
     select floor(dbms_random.value(-50000,50000)) into v_num from dual;
     --将以上的随机数插入
    insert into db_big
      (bigid, bigname, bigdate, bigsex, bignum)
    values
      (sys_guid(), v_bigname, v_bigdate, v_sex, v_num);
    --提交数据
    if  mod(i,1000)=0 then
        commit;   --每插入1000条提交一次
    end if;
  end loop;
end;

表分区

表分区详细介绍

当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表;当数据超过百万条建议分区;建议分区个数为2的n次幂;
表分区分为 1、范围分区 2、列表分区3、散列分区4、组合分区

create tablespace aaa datafile
'G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLLZY\aaa.DBF' ----(创建的路径)
size 20M                   ----(创建的大小)
autoextend on next 5M     ------(数据自动扩展度)
maxsize 100M            --------(最大扩展度)

create tablespace bbb datafile
'G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCLLZY\bbb.DBF' ----(创建的路径)
size 20M                   ----(创建的大小)
autoextend on next 5M     ------(数据自动扩展度)
maxsize 100M            --------(最大扩展度)
--根据时间进行范围分区
create table STUDENT(
 id  varchar2(20),
 name varchar2(20),
 birthday date,
 type varchar2(20)
)
partition by range(birthday)
(
   partition  S80 values less than (to_date('1990-01-01','yyyy-mm-dd')) TABLESPACE aaa,
   partition  S90 values less than (to_date('2000-01-01','yyyy-mm-dd')) TABLESPACE bbb
)

--根据id分区进行范围分区
CREATE TABLE CUSTOMER
(
    CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY,
    FIRST_NAME  VARCHAR2(30) NOT NULL,
    LAST_NAME   VARCHAR2(30) NOT NULL,
    PHONE        VARCHAR2(15) NOT NULL,
    EMAIL        VARCHAR2(80),
    STATUS       CHAR(1)
)
PARTITION BY RANGE (CUSTOMER_ID)
(
    PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE aaa,
    PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE bbb
)
--根据地点,或者部门进行list分区
CREATE  TABLE  ListTable
(
    id    INT  PRIMARY  KEY ,
    name  VARCHAR (20),
    area  VARCHAR (10)
)
PARTITION  BY  LIST (area)
(
    PARTITION  part1 VALUES ('guangdong','beijing') TABLESPACE  aaa,
    PARTITION  part2 VALUES ('shanghai','nanjing')  TABLESPACE  bbb
)

--根据字段进行散列分区,散列分区建议使用2的n次幂个区,可以使数据等到均等分配
CREATE TABLE HASH_TABLE
(
  COL NUMBER(8),
  INF VARCHAR2(100)
)
PARTITION BY HASH (COL)
(
  PARTITION PART01 TABLESPACE HASH_TS01,
  PARTITION PART02 TABLESPACE HASH_TS02,
  PARTITION PART03 TABLESPACE HASH_TS03
)
--查询特定分区中的数据  表名和分区名
select * from student partition(S80)
--显示数据库所有分区表的信息:
select * from DBA_PART_TABLES 
--删除分区表一个分区的数据是
alter table table_name truncate partition p5; 

--新增分区
alter table graderecord add partition S_01
--删除分区
alter table table_name drop partition S_4
--合并分区
ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2

sql优化

小表驱动大表

exists代替distinct

extist 代替 in

使用exists 替代distinct
select distinct d.dp_id,d.dp_name from depts d,staffs s where d.dp_id=s.dp_id;
select d.dp_id,d.dp_name from depts d where exists(select 1 from staffs s where s.dp_id=d.dp_id)
用* 替代查询的列名
合理应用where,在having 前进行过滤;
使用truncate 替代delete,其中不用commit,不会记录日志,要清空表中全部数据,不会清空表格式,比如索引;
在确保完整性的时候多使用commit;commit后会释放内存;
减少查表次数,可以左连接,或者使用union
合理安排from后面表的顺序,from扫描表顺序是从右到左,最先被扫描的先被处理,先被处理的表叫做基表,要将数据量小的表放到最右面;
where中执行顺序也是从右到左,要将过滤条件排除多的判断放到右面;
使用not exists 替代not in ,代码如下在这里插入图片描述
在这里插入图片描述

count使用

count(*)count(1)count(主键列)  结果执行一样只是在优化上不同
如果有主键,则 select count(主键)的执行效率是最优的
如果表有多个字段,则 select count(*)最优
如果表只有一个字段,则 select count(1)最优
列名不为主键,count(1)会比count(列名)

START WITH CONNECT BY PRIOR的使用

一般用于部门等信息关联时进行查询
创建部门表,这是一个具有层次结构的表,子记录通过parent_id与父记录的id进行关联

--书写格式格式 
select child_id, parent_id, level as lv
from table_name
start with child_id = 10
connect by (prior child_id) = parent_id;

--例子
create table DEPT( 
ID NUMBER(9) PRIMARY KEY       --部门ID 
NAME VARCHAR2(100),             --部门名称
PARENT_ID NUMBER(9) --父级部门ID,通过此字段与上级部门关联
); 
--对查询结果过滤
select * from dept where name like '%销售%' start with id=1 connect by prior id = parent_id;
sql执行顺序,在查询结果中可以看到,首先使用start with... connect by prior查询出树形的结构,然后where条件才生效,对全部查询结果进行过滤
--prior关键字表示不进行递归查询,仅查询出满足id=10的记录

rownum三层子查询的优化

oracle中三层子查询
oracle中子查询中使用rowNum,rowNum是计算列,rowNum是虚拟的不存在的,rownum是在产生结果集时候产生的
首先了解下rownum是什么时候产生的

--这句话是可以执行的说明rownum在group by 之前就已经产生了
select rownum from db_stu group by rownum
--在where中也是好使的,说明在where时产生或者在from时产生
select rownum from db_stu where rownum<10

了解rowNum是计算列

--这句话是查询不到rownum的,因为rowNum是计算列,要从小到大产生
select rownum from db_stu where rownum>10
--要这样查询则可以查询到
select rownum from db_stu where rownum<10

如果查询的数据使用了group by,hanving,order by进行了查询要使用第二层子查询,因为rownum是在where时产生的,后面进行分组、过滤、排序会将rownum打乱顺序所以使用第二层子查询;
使用第三层子查询
因为rownum是计算列,必须查询rownum之前的所有数据,如果分页查询不是第一页的数据则查询不到所以使用第二层子查询;

select *
  from (select a.*, rownum as num
          from (select * from db_stu order by stuno) a
         --在这层查询进行提前对rownum进行过滤,大大的提高效率
         where rownum < 10) aa
 where num > 5

序列使用场景sql执行顺序

1.from
2.on
3 join
4.where
5.group by
6.avg sum(聚合函数)
7.having
8.select
9.distinct
10.order by

--首先select 是在where后执行的,所以select 中 as 的字段名在where中是不能使用的比如
--这样是使用不了的,因为select在where后面执行
select money as m from tableB where m=10;

动脑sql题

例题1 关联查询时过滤关联数据

--环境如下
create table tableA(
num varchar2(20),
type varchar2(10)
);
create table tableB(
num varchar2(20),
money number(16,4)
);
insert into tableA values('1','000');
insert into tableA values('1','001');
insert into tableA values('1','002');
insert into tableA values('1','003');
insert into tableB values('1',10);
insert into tableB values('1',10);
insert into tableB values('1',10);
insert into tableB values('1',10);
--tableA和tableB以num字段多对多关系;

要求得到下面结果;
tableA中数据全部展示,在tableA中的TYPE为000时,根据关联tableB表中的money的总和显示出来;
在这里插入图片描述
答案:首先将000在table表中用常量查询出来,然后tableA left join 这个常量,结果是如果tableA中这个字段是000则将tableB中的数据显示;

select a.*,b.money from tableA a,(select num,sum(money) money,'000' as code from tableB group by num) b where a.num=b.num(+) and a.type = b.code(+)

--或
select  aa.num,aa.type,sum(bb.money) from tablea aa  left join tableb bb on aa.num=bb.num and aa.type='000' group by aa.num,aa.type

--或
select  aa.num,aa.type,case  aa.type when '000'  then sum(bb.money) else null end  from tablea aa  left join tableb bb on aa.num=bb.num group by aa.num,aa.type

例题2 去除重复数据

--环境如下
create table DB_STU
(
  STUNO VARCHAR2(32),
  SCORE NUMBER(3,1),
  CNAME VARCHAR2(20)
)
;
insert into DB_STU (STUNO, SCORE, CNAME)
values ('1', 85, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('1', 85, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('1', 85, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 67, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 88, '语文');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 88, '语文');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 88, '语文');
commit;

答案:使用rowid 进行分组,然后取出最大值进行去重,对重复的列 group by

select * from DB_STU
--因为使用了group by,select后面查询的数据必须是聚合函数,或者分组列,或者常量
select max(rowid) from DB_STU group by STUNO,score,cname
--通过rowid去掉重复数据
delete  from DB_STU where rowid not in (select max(rowid) from DB_STU group by STUNO,score,cname)

例题3 将行转换成列

create table DB_STU
(
  STUNO VARCHAR2(32),
  SCORE NUMBER(3,1),
  CNAME VARCHAR2(20)
);
insert into DB_STU (STUNO, SCORE, CNAME)
values ('1', 85, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('1', 64, '语文');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('1', 90, '英语');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 67, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 88, '语文');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('2', 89, '英语');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('3', 50, '数学');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('3', 80, '语文');
insert into DB_STU (STUNO, SCORE, CNAME)
values ('3', 75, '英语');
commit;

将行转换成列
在这里插入图片描述
答案

--这个题说明了使用group by分组后,的其他字段还是可以可以显示出来的,但是还是要借助聚合函数
select stuno,
 sum(decode(cname,'数学',score,0)) as 数学,
 sum(decode(cname,'语文',score,0)) as 语文,
  sum(decode(cname,'英语',score,0)) as 英语
 from DB_STU group by stuno

例题5 没有使字符串拼接的聚合函数怎么办

有一个很值得思考的需求
在一个公文系统中,程序可以流转到不同节点
根据指定节点,和公文id去查询流程上的人

环境

--公文表
create table wen(
gw_id varchar2(32) --公文id
);
--流程表
create table flow(
gw_id varchar2(32),
jiedian varchar2(32), --节点
people varchar2(32) --这个节点上的人
);
--公文表和流程表是1对多关系
insert into wen values('1');
insert into flow values('1','收文节点','陈小云');
insert into flow values('1','收文节点','武松');

要得到的结果
在这里插入图片描述
使用下面语句得到结果(这中结果并不符合需求)
select * from wen a,(select * from flow) b where a.gw_id=b.gw_id
在这里插入图片描述
答案
想了好长时间也没有能一条sql查询出想要的数据,最终解决办法如下

--首先创建一个方法
CREATE OR REPLACE FUNCTION fn_simpleTest2(v_where_sql in varchar2)
  return varchar2 is
  testStr varchar2(4000);
begin
  for tempCur in (select distinct(people) from flow where gw_id = v_where_sql) loop
    testStr := testStr || tempCur.PEOPLE || ',';
  end loop;
  return testStr;
end;
--执行sql
select a.*,b.jiedian,fn_simpleTest2(a.gw_id) from wen a,(select * from flow) b where   a.gw_id=b.gw_id; 

例题6 索引怎么创建

这样的查询如何创建索引
在这里插入图片描述
答案:
如果是左关联则要对右面字段创建索引
在这里插入图片描述

例题7 插入去重

要求进行测试,但是表中没有数据,需要将 tableA 表中的数据插入到 tableB 本表中
执行代码如下insert into tableB(A,B,C,D) select A,B,C,D from tableA;
B表中有重复数据,A表中A,B,C为主键,插入时报主键冲突;要如何插入才能不违反主键将数据插入?

解决办法1:使用distinct

distinct 是关键字不是方法,它能对查询出来的每一列去重(查几列就要对几列去重)
select distinct a,b,c,d from tableB; distinct多列的使用
select distinct (a),b,c,d from tableB; 和不加括号效果相同

--解决思路如下,发现不好使
insert into tableB(A,B,C,D)  select  distinct A,B,C,D from tableA;
--这样使用是不管用的因为
select  distinct A,B,C,D from tableA; 相当于 select A,B,C,D from tableB group by A,B,C,D
--因为查询的结果只对A,B,C进行去重,不用对D去重

结论: 使用了distinct关键字就要对查询的所有列去重,不能查4列只对3列去重

解决办法2:使用rowid

--使用rowid解决的代码如下
select A,B,C,D from tableA where rowid  in 
(select max(rowid) from tableB group by A, B,C)

例题八 用一条sql语句查找记录中的连续数据

在这里插入图片描述
在这里插入图片描述

建表sql如下

create table NBA
(
Team varchar2(20),
Y varchar2(4)
);

insert into NBA values('活塞','1990');
insert into NBA values('公牛','1991');
insert into NBA values('公牛','1992');
insert into NBA values('公牛','1993');
insert into NBA values('火箭','1994');
insert into NBA values('火箭','1995');
insert into NBA values('公牛','1996');
insert into NBA values('公牛','1997');
insert into NBA values('公牛','1998');
insert into NBA values('马刺','1999');
insert into NBA values('湖人','2000');
insert into NBA values('湖人','2001');
insert into NBA values('湖人','2002');
insert into NBA values('马刺','2003');
insert into NBA values('活塞','2004');
insert into NBA values('马刺','2005');
insert into NBA values('热火','2006');
insert into NBA values('马刺','2007');
insert into NBA values('凯尔特人','2008');
insert into NBA values('湖人','2009');
insert into NBA values('湖人','2010');
comment on;

答案如下

--通过队名与队名、年份 与(年份+1) 关联,然后根据队名分组,得出了连续夺冠的数据
--然后根据(年份-rownum)分组,得出分组中对大年和最小年份
select min(t4.col4),
       (col3 - rownum) + min(rownum) - 1,
       (col3 - rownum) + count(*) + min(rownum) - 1
  from (select t3.*, rownum
          from (select max(col2) as col4, col3
                  from (select t1.team as col2,
                               t1.y as col3,
                               t2.team as col1,
                               t2.yy
                          from nba t1
                          left join (select team, y + 1 as yy from nba) t2 on t1.y =
                                                                              t2.yy
                                                                          and t1.team =
                                                                              t2.team)
                 where col1 is not null
                 group by col3
                 order by col3) t3) t4
 group by (col3 - rownum)
 order by (col3 - rownum)

自定义sql排序规则

select * from counter.tb_pac_account_glide_pe where COMPARE_BATCH_NO = "25465789361671273" GROUP BY BIZ_NO ORDER BY (case when COMPARE_FLAG ='I' then '0' when COMPARE_FLAG='L' then '1' when COMPARE_FLAG='W' then '2' when COMPARE_FLAG='U' then '3' else COMPARE_FLAG end) ASC

一次线上事故 insert into ** select * from

我要将数据从一个表中迁移到另一个表中,使用如下sql
insert into tableA select * from tableB where createTime > ‘2018-12’
如果是在线上执行的话就有可能出现问题,这句sql不会走索引导致全表扫描,扫描的数据都会上锁,如果处理时间过长则可能导致查时间此表不可用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值