精华内容
下载资源
问答
  • 本次测试使用数据库版本为5.7 初始化sql语句:CREATE TABLE `film` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_name` (`name`) ) ENGINE=...

    6460a5d57791cc075ec8f29578a8f54c.png

    本次测试使用的数据库版本为5.7 初始化sql语句:

    CREATE TABLE `film` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `idx_name` (`name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    CREATE TABLE `actor` (
      `id` int(11) NOT NULL,
      `name` varchar(45) DEFAULT NULL,
      `update_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    INSERT INTO `xnyh`.`actor`(`id`, `name`, `update_time`) VALUES (1, 'a', '2017-12-02 15:27:18');
    INSERT INTO `xnyh`.`actor`(`id`, `name`, `update_time`) VALUES (2, 'b', '2017-12-22 15:27:18');
    INSERT INTO `xnyh`.`actor`(`id`, `name`, `update_time`) VALUES (3, 'c', '2017-12-22 15:27:18');
    
    INSERT INTO `xnyh`.`film`(`id`, `name`) VALUES (2, 'film 2');
    INSERT INTO `xnyh`.`film`(`id`, `name`) VALUES (3, 'film0');
    INSERT INTO `xnyh`.`film`(`id`, `name`) VALUES (1, 'film1');
    
    CREATE TABLE `film_actor` (
      `id` INT ( 11 ) NOT NULL,
      `film_id` INT ( 11 ) NOT NULL,
      `actor_id` INT ( 11 ) NOT NULL,
     `remark` VARCHAR ( 255 ) DEFAULT NULL,
      PRIMARY KEY ( `id` ),
      KEY `idx_film_actor_id` (
      `film_id`,
     `actor_id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
     INSERT INTO `film_actor` (`id`, `film_id`, `actor_id`) VALUES (1,1,1), (2,1,2),(3,2,1);
    

    先执行exlpain语句,EXPLAIN SELECT * from db,执行结果如下:

    8bd6dc99e92b45cdb42a667f8b13cbe9.png

    我们接下来对这12个字段依次进行解释

    ID列

    id列的值是代表了select语句执行顺序,是和select相关联的;id列的值大会优先执行,如果id列为空最后执行,id列相同,则从上到下依次执行。

    select_type列

    代表查询的类型,有如下几个值:

    simple:

    不包含子查询和join关键字 explain select * from film where id = 2;

    990771b252b999ab0ef7b4d53ad81080.png

    primary:

    复杂查询最外层select语句或者union语句中最左边的select explain select *,(select id from actor where id=1) from film

    e8962b2b1a87d6a5bceb792d17912140.png

    最外层查的是film表的,所以film对应的查询类型就是primary;

    subquery:

    仅限在from前面的select语句,不包括select后面的语句 explain select *,(select id from actor where id=1) from film

    derived:

    衍生表,如果from子句后面包含select语句,则会产生这种类型,它会把中间结果存放在临时表中,但是在5.7中需要使用set session optimizer_switch='derived_merge=off';关闭mysql对衍生表的合并优化,我们先看下不关闭之前,我们执行如下sql的情况: explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;

    79fb7b6c7d4f64866b9fef083f34788f.png

    发现查询类型没有derived,我们关闭优化看下set session optimizer_switch='derived_merge=off'

    29ee79b21c82a976f3a776102c9247ae.png

    发现出现了derived查询了,

    union:

    在 union 中的第二个和随后的 select explain select 1 union select 2 UNION select 3

    87864c8ca466ef3104d1855edb339603.png

    table列

    table列代表当前select语句正在查询哪张表。 EXPLAIN SELECT id from actor UNION select id from film

    4c88998dbdc73b67d0c1a8e718adc0e6.png

    优先执行的是union后面的查询语句当前访问的是film表,接着执行union左边查询语句,当前查询的是actor表,最后查询的是依赖1和2的查询结果,所以使用<union1,2>来代替。

    type列

    type列的值分别为: NULL>system > const > eq_ref > ref > range > index > ALL; 执行效率依次递减。

    NULL:

    代表查询在mysql能够在优化阶段分解查询语句的时候直接能完成,不需要查询表和索引,例如获取逐渐最大列或最小列: EXPLAIN select min(id),max(id) from film

    ba00e354c800b6a0d5bfdba3a665231c.png

    const:

    当where后面是一个主键或者唯一索引 与一个常量精确比较时,mysql会把查询优化为常量查询,执行如下sql: explain select * from film where id = 2

    5c594c50a923767969c1fe3a96e02499.png

    我们可以看下mysql内部进行了如何优化: explain EXTENDED select * from film where id = 2; show WARNINGS;

    fe8cbb456cb3e4e64c5ff55d222939eb.png

    可以看出mysql直接将其转换为常量进行查询

    system:

    如果要达到sysytem级别,那么它必须要达到以下几个条件:

    1.是系统表或者是临时表 2.表中有且只有一条记录

    • 我在mysql库中找到了proxies_priv表,我们看执行如下sql: explain select * from proxies_priv

    424a27ea6714045cb372ebf0f17b8ff6.png

    可以看出已经到了system级别;

    • 我们再看一种情况:派生表(临时表) explain extended select * from (select * from film where id = 1) tmp;

    5c988994395912582ce1901e0268e82e.png

    可以看到查询类型为PRIMARY已经达到了system级别,它是从派生表(临时表)中查询,并且派生表中只有一条记录,也能够达到system级别。

    eq_ref:

    主键或者唯一索引与其它表或字段进行关联查询,最多只会返回一条记录,如下代码: explain select * from film_actor left join film on film_actor.film_id = film.id;

    d6abdb412099e0c72ab835bfde7e986e.png

    可以看出访问film表的时候,type达到了eq_ref级别,因为id字段在film表中是唯一的,所以查询film表的时候按照id查询只会有一条记录与其关联;

    ref:

    相对于eq_ref,ref只需要要求是普通索引或者联合索引的前缀匹配

    • 普通索引查询explain select * from film where name = 'film1';

    8f674ea0110e80e761ece018348250d3.png
    • 联合索引前缀匹配 explain select film_id from film left join film_actor on film.id = film_actor.film_id;

    d906b6720da7b80d1c7d9d56873edbaa.png

    range:

    范围索引,通常为in、> < >= 这样的比较符,会达到range级别 explain select * from actor where id > 1;

    9607d58ecb0a71ca88b137c61ecae6e3.png

    index

    扫描全表索引:所查询的列都创建了索引,但是没有按照索引字段过滤(除了让索引失效的操作除外) explain select * from film

    a938e1ba29875d999201285a5d3d630d.png

    all

    扫描全表,通常情况下,是没有创建索引,需要增加索引优化 explain select * from actor;

    2b6ee32e494889aa29fc297020cafe44.png

    possible_keys

    这一列显示查询可能使用哪些索引来查找。 explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中 数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。 如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查 where 子句看是否可 以创造一个适当的索引来提高查询性能,然后用 explain 查看效果。

    key

    这一列显示mysql实际采用哪个索引来优化对该表的访问。 如果没有使用索引,则该列是 NULL。如果想强制mysql使用或忽视possible_keys列中的索 引,在查询中使用 force index、ignore index。

    key_len

    该列记录了使用索引的长度,一般用来判断联合索引是否全部生效的作用,该值是根据不同数据类型进行计算的。

    key_len计算规则如下:

    • 字符串
      • char(n):n字节长度
      • varchar(n):2字节存储字符串长度,如果是utf-8,则长度 3n + 2
    • 数值类型
      • tinyint:1字节
      • smallint:2字节
      • int:4字节
      • bigint:8字节
    • 时间类型
      • date:3字节
      • timestamp:4字节
      • datetime:8字节

    如果字段允许为 NULL,需要1字节记录是否为 NULL 索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半 部分的字符提取出来做索引。

    在创建表film_actor的时候我们已经创建了联合索引

    KEY `idx_film_actor_id` (`film_id`,`actor_id`)
    

    我们利用这个联合索引进行计算

    • 只使用联合索引的第一个字段: explain select * from film_actor where film_id = 2;

    36577bc1b217ae61b11ad88e2e037086.png

    可以看到key_len是4,我们是根据联合索引字段的第一个字段进行过滤的,我们看下film_id字段的类型的int类型,结合上面的计算方式,file_id不能为NULL,那么key_len就是4;

    53372cb2c6f2f4228c374943df499972.png
    • 使用联合索引的两个字段: explain select * from film_actor where film_id = 2 and actor_id = 3

    661d8bf8efbfec89e8a875f8c939e8d9.png

    发现结果为8,这个因为这两个字段都是int类型,并且都不为NUll,那么加起来索引长度就是8,那就说明这个索引完全生效了。

    ref

    这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常 量),字段名(例:film.id)

    rows

    这一列是mysql估计要读取并检测的行数,注意这个不是结果集里的行数。

    Extra列

    这个展示索引的额外信息,主要字段信息如下:

    • Using index 查询的字段被索引覆盖explain select film_id from film_actor

    95b3db239acc9c7257d212a25853aa83.png
    • using where where 后面的字段没有使用被创建索引,优化方式,创建索引。 explain select film_id from film_actor where remark = '描述';

    7dd47f08c0d08e38c6b57d77ff53b348.png
    • using index condition 查询的语句中,where条件中是一个前导列的范围; explain select * from film_actor where film_id = 1 and actor_id >3;
    • Using temporary 创建临时表,mysql查询过程中需要创建临时表来辅助查询,像这种情况是需要优化的。 explain select distinct name from actor;

    868a6a125407cdb7a2998eb71421b945.png

    通过给去重的字段添加索引,可达到优化的效果 CREATE index idx_name on actor(name)

    b91b396b8f2b705cb8e4dbdb40917e2b.png

    方便后续测试,需要删除刚创建的索引:DROP INDEX idx_name on actor

    • Using filesort 数据排序的时候没有通过索引排序,当数据量小时通过内存排序,大的时候在磁盘中进行排序,需要进行索引优化,通常是排序字段没有创建索引。 explain select * from actor order by name;

    dd2e6f6c32c3fd4ad428a54cf9970f3d.png

    下面的排序字段创建了索引,所以是在索引内进行排序 explain select * from film order by name;

    fff2e69c989bcbfde2f098cdab118655.png
    • Select tables optimized away 对某个创建了索引的字段查询使用了聚合函数 explain select max(id) from actor

    9f52a9071ef29103cf274f1fcbaa8f77.png
    展开全文
  • ORA-00923: 未找到要求的 FROM 关键字

    万次阅读 2017-08-25 15:50:07
    ORA-00923: 未找到要求的 FROM 关键字

    ORA-00923: 未找到要求的 FROM 关键字

    这里写图片描述

    注意:别名不能是数字和使用”

    展开全文
  • ORA-00923: 未找到要求的FROM 关键字
    ORA-00923: 未找到要求的FROM 关键字
    展开全文
  • ora-00923: 未找到要求的 from 关键字

    万次阅读 2018-01-29 11:40:34
    ora-00923: 未找到要求的 from 关键字 oracle 查询时,如果出现该错误,检查sql语句的 是否有关键字,是否语句错误,是否单词,语法拼写错误。 如果查询的语句在 plsql 中测试通过,在程序运行时出现该错误。 ...

    ora-00923: 未找到要求的 from 关键字

    oracle 查询时,如果出现该错误,检查sql语句的 是否有关键字,是否语句错误,是否单词,语法拼写错误。


    如果查询的语句在 plsql 中测试通过,在程序运行时出现该错误。

    如果使用dbcp数据连接池,请排查配置的测试sql是否正确(我的错误就是配置的测试sql错误)。

    ---------以下为数据连接池中的 配置测试sql

    #oracle test select rest
    #ds.validation=select * from dual



    #mysql or sqlserver test select rest
    ds.validation=select 1




    展开全文
  • java.sql.SQLSyntaxErrorException: ORA-00923: 未找到要求的 FROM 关键字 ssm(Oracle)配置druid数据库连接池,正常启动项目,但是请求访问数据库时报错 “java.sql.SQLSyntaxErrorException: ORA-00923: 未找到要求...
  • 今天做数据库操作的时候,发现了一个报错:ORA:00923:未找到要求的FROM关键字。这个错误之前也报过,但是我已经忘了当时是怎么改好的,鉴于以往的错误总是会重复出现,而且我每次都要花费一定的精力去解决同样的...
  • select a.C001,a.C006,a.C012,b.C005,b.C009 case when b.C009='1' then '逗B' end from T_21_001 a full join T_31_019_00000 b on a.C002=b.C003这该怎么写呢?
  • select t.guid t.year from USER t 在from之前报错,一般是少写了”,“
  • 如果有子查询话,检查一下,是否是外层查询末尾是否多写了,号,如果多写了,号话是会报ORACLE要求找到FROM关键字错误
  • 连接数据库一直报错:ORA-00923: 未找到要求的 FROM 关键字 一直核对SQL,各种操作,无用。。 检查SQL语句语法是否正确; 检查SQL语句中是否包含特殊字符; 检查SQL语句结尾是否包含分号; 检查SQL是否包含中文逗号...
  • 一天沙雕问题 我自己在练习nvl()函数,写查询时候。 select * 后面加了又加了表里字段,就会报这个错误。 比如:一张表有两个字段 code,type select * from table;可以查出两个字段分别是code和type 如果...
  • 昨天测试查询的时候发现使用oracle时有这么一个错误:Cannot create PoolableConnectionFactory (ORA-00923: 未找到要求的 FROM 关键字)。 我换成了sqlserver和mysql,发现又没有错误。百思不得其解,因为用ibatis...
  • 我用MAX(DECODE())函数报错:未找到要求的from关键字 这是语句: select fno,max(decode(category,'班组',id,'')) 班组,max(decode(category,'版本',id,'')) 版本,max(decode(category,' 1.OCV',id,'')) OCV,max...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 136
精华内容 54
关键字:

未找到from要求的关键字