面试篇三:数据库MySQLOracle
Posted 时光编辑师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试篇三:数据库MySQLOracle相关的知识,希望对你有一定的参考价值。
- MySQL
- MySQL分页查询
SELECT * FROM admin_company LIMIT 0,10; SELECT * FROM admin_company ORDER BY id LIMIT 0,10;
limit后参数代表什么意思?
LIMIT[位置偏移量,]行数,第一个参数是从哪个序号加上,初始是0,第二个参数是查询多少行记录。
还有没有其他方式?
- MySQL怎么查看执行计划
用explain,如 SELECT * FROM admin_company
https://www.cnblogs.com/scorpio-cat/p/12661216.html
mysql索引
索引分类:主键索引、唯一索引、普通索引、全文索引、组合索引。
MySQL默认会对主键和唯一键列创建索引。
MySQL在创建表时就会创建一主键索引。如果主键存在,则存主键;如果主键不存在,但唯一键存在,则存唯一健;如果主键和唯一健都不存在,则存6个字节的rowid。
索引的优点:减少服务器需要扫描的数据量、帮助服务器避免排序和临时表、将随机io变成顺序io。
索引匹配方式:
(1)全值匹配:where条件为=。
(2)最左前缀匹配:组合索引时,SQL必须包括组合索引指定的第一列;如果不存在,则不会走索引。
(3)列前缀匹配:使用like模糊查询,like \'123%\'。
(4)范围值匹配:between and,> , <,但是索引中,如果包括了范围判断,则会导致后面的查询条件不走索引,只有前面的列和该范围列走索引。
(5)精确匹配某一列并范围匹配另一列。
(6)只访问索引的查询。
https://www.cnblogs.com/scorpio-cat/p/12661379.html
- Oracle
- Oracle分页查询
SELECT * FROM (SELECT ROWNUM rn ,* FROM admin_company WHERE rn <= 10) WHERE rn > 0;
没有ORDER BY,两层查询;如果要排序使用上面两层查询,会出现什么问题?查询结果有问题。
ROWNUM伪列产生的序号是按照数据被查询出来的顺序添加上去的,第一条是1,第二条是2,依次加1。
在ORACLE中使用rownum伪列分页时,需要多加一层查询,以保证rownum序号的连续性。
SELECT * FROM (SELECT ROWNUM rn , c.* FROM (SELECT * FROM admin_company ORDER BY companyno) c WHERE rn <= 10 ) WHERE rn > 0;
当将一条语句交给查询优化器处理时:
如果排序列上有索引,则借助索引去查询数据,这样,读取出来的数据和rownum产生的序号是一种正常的对应关系。
如果排序列上没有索引,则使用全表扫描的方式,依次从表中读取数据,读取完成后,最后进行排序,可能产生的rownum序号不连续。
正是由于排序列上不一定有索引,所以在ORACLE中使用rownum伪列分页时,需要多加一层查询,以保证rownum序号的连续性。
- Oracle怎么查询执行计划
(1)通过使用工具PLSQL Developer中的Explain Plan Window窗口查看SQL执行计划。快捷键为F5。
(2)通过explain plan for explain plan for select *admin_company; 。
- Oracle触发器
Oracle触发器是在事务发生时。隐式地自动执行的PL/SQL代码块,没有参数。
create or replace trigger trigger_name before insert on table_name for each row declare next_id number; begin select seq_test.nextval into next_id from dual; :new.id :=next_id; insert into op_log values(1,\'insert\',sysdate,:next_id); end;
- Oracle存储过程
oracle存储过程,是用于完成一组特定功能的SQL合集。可以有参数,也可以无参数。
CREATE OR REPLACE PROCEDURE 存储过程名称 ( s_no in varchar, s_name out varchar, s_age number ) AS total NUMBER := 0; BEGIN SELECT COUNT(1) INTO total FROM student s WHERE s.age=s_age;
dbms_output.put_line(\'符合该年龄的学生有\'||total||\'人\'); EXCEPTION WHEN too_many_rows THEN DBMS_OUTPUT.PUT_LINE(\'返回值多于1行\'); END
存储过程原文 https://blog.csdn.net/weixin_41968788/article/details/83659164
- Oracle游标
create or replace procedure proc_name is v_date date; --定义变量 cursor cur is select * from ldcode where rownum<10; --定义游标 begin select sysdate into v_date from dual; --游标for循环开始 for temp in cur loop --temp为临时变量名,自己任意起 Dbms_Output.put_line(temp.Code); --输出某个字段,使用"变量名.列名"即可。 end loop; --游标for循环结束 end proc_name;
索引
作用:提高查询速度、确保数据的唯一性、可以加速表和表之间的连接,实现表和表之间的参照完整性、使用分组和排序子句进行数据检索时,可以减少分组和排序的时间、全文检索字段进行搜素优化。
分类:主键索引(PRIMAY KEY)、唯一索引(UNIQUE)、常规索引(INDEX)、全文索引(FULLTEXT)。
主键索引的几种创建方式:确保数据记录的唯一性,主键索引只能有一个。(以下为MYSQL示例)
CREATE TABLE mytable ( ID INT(11) AUTO_INCREMENT PRIMARY KEY, username VARCHAR (16) NOT NULL #或 PRIMARY KEY(`ID`) ) ;
唯一索引的几种创建方式:避免同一个表中某数据列中的值重复,唯一索引可有多个。(以下为MYSQL示例)
(1)创建索引: CREATE UNIQUE INDEX indexName ON mytable(username(length));
(2)修改表结构: ALTER table mytable ADD UNIQUE [indexName] (username(length));
(3)创建表时指定:
CREATE TABLE mytable ( ID INT NOT NULL, username VARCHAR (16) NOT NULL, UNIQUE [ indexName ] (username (LENGTH)) # 或者username VARCHAR(16) NOT NULL UNIQUE ) ;
常规索引的几种创建方式:快速定位特定数据,应加在查询条件的字段,不易添加太多常规索引,影响数据的插入,删除和修改操作,使用KEY或INDEX关键字设置。(以下为MYSQL示例)
(1)创建表时添加:
CREATE TABLE mytable ( ID INT NOT NULL, userno VARCHAR (16) NOT NULL, username VARCHAR (16) NOT NULL, loginname VARCHAR (16) NOT NULL, INDEX `index1` (userno, username), KEY `index2` (userno, loginname) ) ;
(2)创建后追加: ALTER TABLE `mytable` ADD INDEX `ind` (`userno`,`username`);
全文索引的几种创建方式:快速定位特定数据,只能用于MyISAM类型的数据表,只能用于CHAR ,VARCHAR,TEXT数据列类型。(以下为MYSQL示例)
(1)创建表时添加:
CREATE TABLE mytable( username VARCHAR (16) NOT NULL, FULLTEXT(`username`) )ENGINE=MYISAM;
(2)创建后追加: ALTER TABLE mytable ADD FULLTEXT(`username`);
SQL怎么优化执行效率更高、SQL优化经验
(1)SELECT子句中避免使用‘*’:Oracle在解析的过程中, 会将‘*’依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。
(2)使用表的别名(Alias): 当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。
(3)用IN来替换OR、用UNION替换OR (适用于索引列)、用EXISTS替代IN、用NOT EXISTS替代NOT IN。
(4)如果不需要去重,用UNION-ALL 替换UNION:UNION 将对结果集合进行合并和排序,这个操作会使用到SORT_AREA_SIZE这块内存,UNION ALL 将重复输出两个结果集合中相同记录,排序也不是必要的,效率就会因此得到提高。
(5)优化GROUP BY:提高GROUP BY 语句的效率,可以通过将不需要的记录在GROUP BY 之前过滤掉。
(6)使用DECODE函数来减少处理时间。【TODO】
(7)用Where子句替换HAVING子句:HAVING 只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。
(8)合理使用索引:
①避免在索引列上使用NOT,当Oracle“遇到”NOT,他就会停止使用索引转而执行全表扫描。
②避免在索引列使用 !=、||、+,WHERE子句中,优化器将不使用索引而使用全表扫描。
③避免在索引列上使用计算。WHERE子句中,如果索引列是函数的一部分。优化器将不使用索引而使用全表扫描。
④避免在索引中使用任何可以为空的列,Oracle将无法使用该索引。对于单列索引,如果列包含空值,索引中将不存在此记录。对于复合索引,如果每个列都为 空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中。
⑤总是使用索引的第一个列:如果索引是建立在多个列上,只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引。这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略 了索引。
⑥避免对WHERE子句的列名使用函数(避免改变索引列的类型):当比较不同数据类型的数据时,如
SELECT * FROM EMP WHERE EMPNO = TO_NUMBER(\'123\'); #类型转换没有发生在索引列上,索引的用途没有被改 SELECT * FROM EMP WHERE TO_NUMBER(EMPNO)=123; #类型转换发生在索引列上,索引失效
MySQL和Oracle的区别
链接https://www.cnblogs.com/xu-cceed3w/p/8824199.html https://www.jianshu.com/p/eb4e6c026035?utm_source=oschina-app
(1)分页查询,mysql是limit,oracle是rownum和嵌套查询。
(2)自增:oracle需建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段;mysql有自动增长的数据类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT,使用AUTO_INCREMENT。
(3)默认的事务隔离级别:mysql是RR,oracle是RC。mysql默认是自动提交,而Oracle默认不自动提交,需要用户手动提交。
(4)保存数据的持久性:mysql是在数据库更新或者重启,则会丢失数据;Oracle把提交的sql操作线写入了在线联机日志文件中,保持到了磁盘上,可以随时恢复。
(5)锁的区别:mysql的行级锁依赖于索引,如果sql没有使用索引,则仍然是表级锁。oracle行级锁是在数据库中的数据行上,不依赖与索引。
(6)mysql是轻量级,免费;oracle是重量级,收费。
(7)oracle对数据恢复、异常应对、管理工具、诊断性能调优等更加出色,mysql不够完善。
(8)语法异同:
递归查询,oracle支持start with … connect by prior id = pId,mysql不支持。
对于null返回0,oracle使用nvl函数nvl(参数,0),mysql使用IFNULL(参数,0)
函数。
列转行,Oracle列转行函数可以用vm_comcat函数,mysql的用concat_ws函数。
对时间处理,Oracle是to_date(\'2020-04-12 12:37:13\', \'yyyy-mm-dd hh24:mi:ss\'),Mysql是str_to_date(\'2020-04-12 12:37:13\', \'%Y-%m-%d %H:%i:%s\')。
拼接字符串,oracle可使用||,mysql没有,需使用函数concat(str1,str2,...)或concat_ws(分隔符,str1,str2,...)。
以上是关于面试篇三:数据库MySQLOracle的主要内容,如果未能解决你的问题,请参考以下文章