Oracle中基于hint的3种执行计划控制方法详细介绍

hint(提示)无疑是最基本的控制执行计划的方式了;通过在SQL语句中直接嵌入优化器指令,进而使优化器在语句执行时强制的选择hint指定的执行路径,这种使用方式最大的好处便是方便和快捷,定制度也很高,通常在对某些SQL语句执行计划进行微调的时候我会首选这种方式,不过尽管如此,hint在使用中仍然有很多不可忽视的问题;

使用hint过程中有一些值得注意的细则,首先便是要准确的识别对应的查询块,如果需要使用注释也可以hint中声明;对于使用别名的对象一律使用别名来引用,并且诸如“用户名.对象”的引用方式也不被允许,这几个都是我平时经常犯的错误,其实细心一点也就没什么关系了,不过最郁闷的是使用hint的过程中没有任何提示信息可以参考!!譬如语句中使用了无效的hint,Oracle并不会给予你任何相关的错误信息,相反这些hint会在执行时被默默的忽略,像什么都没发生一样。。

到这里,我并不想讨论如何正确的使用hint,我想说的是在Oracle中,仍然有很多可以控制执行计划的机制,11g中,有三种基于优化器hint的执行计划控制方式:

1.OUTLINE(大纲)
2.SQL PROFILE(概要文件)
3.SQL BASELINE(基线)

这些方式的使用比较hint更加的系统,完备,它们的出现很大程度上提高了hint这种古老的控制方式的实用性。

OUTLINE(大纲)

OUTLINE的原理是解析SQL语句的执行计划,在此过程中确定一套可以有效的强制优化器选择某个执行计划的hints,然后保存这些hints,当下次发生”相同“查询的时候,优化器便会忽略当前的统计信息因素,选用OUTLINE中记录的hints来执行查询,达到控制执行计划的目的。

OUTLINE的创建通常有两种方式,一种使用create outline语句,另一种便是借助于专属的DBMS_OUTLN包,使用Create outline方式时我们需要注明完整查询语句:

代码如下:

SQL> create outline my_test_outln for category test on
  2  select count(*) from scott.emp;

Outline created.

相比之下,DBMS_OUTLN.CREATE_OUTLINE方式允许通过已经保存在缓存区中的SQL语句的hash值来创建outline,因此更加常用,下面是签名:

代码如下:

DBMS_OUTLN.CREATE_OUTLINE (
   hash_value    IN NUMBER,
   child_number  IN NUMBER,
   category      IN VARCHAR2 DEFAULT 'DEFAULT');

category用于指定OUTLINE的分类,在一个会话中只能使用一种分类,分类的选择由参数USE_STORED_OUTLINES决定,该参数的默认值为FALSE,表示不适用OUTLINE,设置成TRUE则选用DEFAULT分类下的OUTLINE,如果需要使用非DEFAULT分类下的OUTLINE,可以设置该参数值为对应的分类的名称。

关于OUTLINE的视图通常可以查询DBA_OUTLINES,DBA_OUTLINE_HINTS,数据库中OUTLN用户下也有三张表用于保存OUTLINE信息,其中OL#记载了每一个OUTLINE的完整定义。

代码如下:

SQL> select TABLE_NAME,OWNER from all_tables where owner='OUTLN';

TABLE_NAME                     OWNER
------------------------------ ------------------------------
OL$                            OUTLN
OL$HINTS                       OUTLN
OL$NODES                       OUTLN

-- 查询当前系统中已有的OUTLINE已经对应OUTLINE使用的hints:
[sql]
SQL> select category,ol_name,hintcount,sql_text from outln.ol$;

CATEGORY   OL_NAME                         HINTCOUNT SQL_TEXT
---------- ------------------------------ ---------- --------------------------------------------------
TEST       MY_TEST_OUTLN                           6 select count(*) from scott.emp
DEFAULT    SYS_OUTLINE_13080517081959001           6 select * from scott.emp where empno=7654

-- 查询对应OUTLINE上应用的hints
SQL> select name, hint from dba_outline_hints where name = 'SYS_OUTLINE_13080517081959001';

NAME                           HINT
------------------------------ --------------------------------------------------------------------------------
SYS_OUTLINE_13080517081959001  INDEX_RS_ASC(@"SEL$1" "EMP"@"SEL$1" ("EMP"."EMPNO"))
SYS_OUTLINE_13080517081959001  OUTLINE_LEAF(@"SEL$1")
SYS_OUTLINE_13080517081959001  ALL_ROWS
SYS_OUTLINE_13080517081959001  DB_VERSION('11.2.0.1')
SYS_OUTLINE_13080517081959001  OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
SYS_OUTLINE_13080517081959001  IGNORE_OPTIM_EMBEDDED_HINTS

6 rows selected.

使用OUTLINE来锁定执行计划的完整实例:

代码如下:

-- 执行查询
SQL> select * from scott.emp where empno=7654;

EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30

-- 查看该查询的执行计划
-- 注意这里的hash_value和child_number不可作为DBMS_OUTLN.CREATE_OUTLINE参数值,这些只是PLAN_TABLE中保存的执行计划的值!!!
SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID  40t73tu9dst5y, child number 1
-------------------------------------
select * from scott.emp where empno=7654

Plan hash value: 2949544139

------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |      1 |        |      1 |00:00:00.01 |       2 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |      1 |      1 |      1 |00:00:00.01 |       1 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("EMPNO"=7654)

19 rows selected.

-- 通过v$sql视图获取查询sql语句的hash_value和child_number
SQL> select sql_id,hash_value,child_number,sql_text from v$sql
  2  where sql_text like 'select * from scott.emp where empno%';

SQL_ID        HASH_VALUE CHILD_NUMBER SQL_TEXT
------------- ---------- ------------ --------------------------------------------------
40t73tu9dst5y 2463917246            0 select * from scott.emp where empno=7654

-- 创建OUTLINE,指定为默认DEFAULT分类
SQL> exec dbms_outln.create_outline(2463917246,0,'DEFAULT');

PL/SQL procedure successfully completed.

-- SESSION级别设置USE_STORED_OUTLINES参数为TRUE,启用OUTLINE
SQL> ALTER SESSION SET USE_STORED_OUTLINES=TRUE;

Session altered.

-- 重新执行查询,可以看到计划与原先的一致,同时在执行计划的Note中显示了使用了outline "SYS_OUTLINE_13080517081959001"
SQL> set autotrace traceonly
SQL> select * from scott.emp where empno=7654;

Execution Plan
----------------------------------------------------------
Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    38 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("EMPNO"=7654)

Note
-----
   - outline "SYS_OUTLINE_13080517081959001" used for this statement

Statistics
----------------------------------------------------------
       1495  recursive calls
        147  db block gets
        262  consistent gets
          5  physical reads
        632  redo size
        896  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
         24  sorts (memory)
          0  sorts (disk)
          1  rows processed

使用非DEFAULT分类下的OUTLINE

代码如下:

-- 查看当前可用的OUTLINE
SQL> select category,ol_name,hintcount,sql_text from outln.ol$;

CATEGORY   OL_NAME                         HINTCOUNT SQL_TEXT
---------- ------------------------------ ---------- --------------------------------------------------
TEST       MY_TEST_OUTLN                           6 select count(*) from scott.emp
DEFAULT    SYS_OUTLINE_13080517081959001           6 select * from scott.emp where empno=7654

-- 设置使用test分类下的OUTLINE
SQL> ALTER SESSION SET USE_STORED_OUTLINES=test;

Session altered.

-- 执行计划Note显示使用了OUTLINE "MY_TEST_OUTLN"
SQL> set autotrace traceonly
SQL> select count(*) from scott.emp;

Execution Plan
----------------------------------------------------------
Plan hash value: 2937609675

-------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |     1 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE  |        |     1 |            |          |
|   2 |   INDEX FULL SCAN| PK_EMP |    14 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------

Note
-----
   - outline "MY_TEST_OUTLN" used for this statement

Statistics
----------------------------------------------------------
         34  recursive calls
        148  db block gets
         22  consistent gets
          0  physical reads
        540  redo size
        526  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
          1  rows processed

关于OUTLINE的一些注意事项:

1,OUTLINE匹配SQL语句有点类似cusor_sharing参数中的similar,也就是说即使不同hash值的SQL语句也可能使用相同的OUTLINE,如:

代码如下:

SQL> ALTER SESSION SET USE_STORED_OUTLINES=test;

Session altered.

-- 使用不相同的SQL语句 同样使用了和之前相同的OUTLINE
SQL> set autotrace traceonly
SQL> SELECT COUNT(*)FROM scott.emp;

Execution Plan
----------------------------------------------------------
Plan hash value: 2937609675

-------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |     1 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE  |        |     1 |            |          |
|   2 |   INDEX FULL SCAN| PK_EMP |    14 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------

Note
-----
   - outline "MY_TEST_OUTLN" used for this statement

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        526  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

-- 查询v$sql可以看到两条语句是不同的
SQL> select sql_id,hash_value,child_number,sql_text from v$sql
  2  where sql_text like '%scott.emp%';

SQL_ID        HASH_VALUE CHILD_NUMBER SQL_TEXT
------------- ---------- ------------ --------------------------------------------------
6xydpctfbwbm6 1555967590            0 select sql_id,hash_value,child_number,sql_text fro
                                      m v$sql where sql_text like '%scott.emp%'
40t73tu9dst5y 2463917246            0 select * from scott.emp where empno=7654
abj9tmfcs15bm 2575340915            0 select count(*) from scott.emp
d16cs4nzg9vmk 1056239218            0 SELECT COUNT(*)FROM scott.emp

2,DBMS_OUTLN.CREATE_OUTLINE中hash_value的是SQL语句的hash值,不是sql_id,也不是执行计划的hash_value。

3,DBMS_OUTLN.CREATE_OUTLINE无法像Create outline语句那样自定义outline的名称,这种方式创建的outline名称是系统自动生成的,需要可以手动使用alter outline语句来修改。

4,可以通过v$sql中的OUTLINE_SID和OUTLINE_CATEGORY字段查询到已经记录到大纲中的sql语句。

代码如下:

select sql_id,hash_value,child_number,OUTLINE_SID,OUTLINE_CATEGORY,sql_text from v$sql
where sql_text like '%scott.emp%'

SQL_ID        HASH_VALUE CHILD_NUMBER OUTLINE_SID OUTLINE_CA SQL_TEXT
------------- ---------- ------------ ----------- ---------- ---------------------------------------------
6xydpctfbwbm6 1555967590            0                        select sql_id,hash_value,child_number,sql_tex
                                                             t from v$sql where sql_text like '%scott.emp%'
40t73tu9dst5y 2463917246            0             DEFAULT    select * from scott.emp where empno=7654
abj9tmfcs15bm 2575340915            0             TEST       select count(*) from scott.emp
d16cs4nzg9vmk 1056239218            0             TEST       SELECT COUNT(*)FROM scott.emp

SQL Profile(SQL概要文件)

SQL Profile基本上相当于OUTLINE的升级版本,也是功能上最强大的,很多时候都是在使用SQL优化顾问(SQL Tuning Advisor,STA)才会接触到,同OUTLINE相同,SQL Profile同样由一系列hint组成,使用SQL Profile我们可以在SQL语句执行的同时后台应用这些hint从而达到维持执行计划稳定性的目的,事实上,相对OUTLINE它还具备一些特有的优势,比如允许概要文件通过忽略常量应用到多条SQL语句上,同时还可以将任意hint集合与指定的SQL语句结合起来!!

在使用SQL Profile的过程中,参数SQLTUNE_CATEGORY实现了和OUTLINE中的USER_STORED_OUTLINE参数一样的功能,于此同时,概要文件也会默认创建到DEFAULT分类中,通过为SQLTUNE_CATEGORY参数指定不同的分类名称来启用对应分类的SQL Profile;通常我们都是使用STA来创建概要文件,其实这些操作都直接间接的使用了DBMS_SQLTUNE.IMPORT_SQL_PROFILE过程,调用签名如下:

代码如下:

PROCEDURE IMPORT_SQL_PROFILE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SQL_TEXT                       CLOB                    IN
 PROFILE                        SQLPROF_ATTR            IN
 NAME                           VARCHAR2                IN     DEFAULT
 DESCRIPTION                    VARCHAR2                IN     DEFAULT
 CATEGORY                       VARCHAR2                IN     DEFAULT
 VALIDATE                       BOOLEAN                 IN     DEFAULT
 REPLACE                        BOOLEAN                 IN     DEFAULT
 FORCE_MATCH                    BOOLEAN                 IN     DEFAULT
PROCEDURE IMPORT_SQL_PROFILE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SQL_TEXT                       CLOB                    IN
 PROFILE_XML                    CLOB                    IN
 NAME                           VARCHAR2                IN     DEFAULT
 DESCRIPTION                    VARCHAR2                IN     DEFAULT
 CATEGORY                       VARCHAR2                IN     DEFAULT
 VALIDATE                       BOOLEAN                 IN     DEFAULT
 REPLACE                        BOOLEAN                 IN     DEFAULT
 FORCE_MATCH                    BOOLEAN                 IN     DEFAULT

可以看到SQL Profile的创建是通过对SQL_TEXT指定hint集来完成的,并非OUTLINE中的HASH_VALUE,同时PROFILE字段的类型显示使用的SQLPROF_ATTR,PROFILE_XML字段也是需要通过获取V$SQL_PLAN视图的OTHER_XML字段来填充hint集的,可惜的是在官档中并没有提及这一概要文件的重要过程,因此无法详细了解它的使用细节,实际使用中还是建议使用STA来完成SQL Profile的创建。Kerry Osborne曾利用该过程来实现通过SQL_ID来创建SQL Profile,同时给出了利用IMPORT_SQL_PROFILE过程自定义hint集合来强制改变执行计划的解决方案【可以访问kerryosborne.oracle-guy.com获取详细信息】

基线(BASELINE)

BASELINE更像是一个性能的指标,oracle会通过基线来维护和消除系统的性能退化,基线的核心是一套具有特定名称并与特定语句相联系的hint,它可以像概要文件一样匹配SQL语句,虽然对计划的控制能力没有概要文件那么灵活,但它仍然是限制计划不稳定性的重要方法,下面是基线的一些特点:
1,基线中不存在分类category。
2,每个SQL语句可以有多个基线,比如固定基线集合。
3,基线保存了hint和执行计划的hash_value,因此优化器在判定是否采用基线时还需要验证是否有对应的计划存在。
4,可以通过设置OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES为true来为每一条执行过的SQL语句自动创建基线,默认情况下不会创建基线。
5,通过查询视图DBA_SQL_PLAN_BASELINES可以获得已经创建的基线。
6,使用dbms_spm.load_plans_from_cursor_cache过程可以为一条缓存的SQL语句创建基线。
7,在11g中,默认会使用已经存在的基线维持执行计划的稳定性。

为指定SQL语句创建基线

代码如下:

-- 仍然使用OUTLINE中的示例查询
SQL> select * from scott.emp where empno=7654;

EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30

SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------
SQL_ID  40t73tu9dst5y, child number 0
-------------------------------------
select * from scott.emp where empno=7654

Plan hash value: 2949544139

------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |      1 |        |      1 |00:00:00.01 |       2 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |      1 |      1 |      1 |00:00:00.01 |       1 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("EMPNO"=7654)

19 rows selected.

-- 创建BASELINE,注意参数为SQL_ID和PLAN_HASH_VALUE
SQL> var ret number
SQL> exec :ret := dbms_spm.load_plans_from_cursor_cache(-
>     sql_id=>'&sql_id', -
>     plan_hash_value=>&plan_hash_value,-
>     fixed=>'&fixed');
Enter value for sql_id: 40t73tu9dst5y
Enter value for plan_hash_value: 2949544139
Enter value for fixed: NO

PL/SQL procedure successfully completed.

-- 再次运行查询可以发现在执行计划输出的Note中显示使用了基线SQL_PLAN_bmwra43zx42kr695cc014
SQL> set autotrace traceonly
SQL> select * from scott.emp where empno=7654;

Execution Plan
----------------------------------------------------------
Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    38 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("EMPNO"=7654)

Note
-----
   - SQL plan baseline "SQL_PLAN_bmwra43zx42kr695cc014" used for this statement

Statistics
----------------------------------------------------------
        747  recursive calls
         14  db block gets
        117  consistent gets
          0  physical reads
       2956  redo size
       1028  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

(0)

相关推荐

  • Oracle中直方图对执行计划的影响详解

    前言 大家应该都知道,在Oracle数据库中,CBO会默认目标列的数据在其最小值low_value和最大值high_value之间均匀分布,并按照均匀分布原则,来计算目标列 施加查询条件后的可选择率以及结果集的cardinality. 如果对目标收集了直方图,则意味着CBO不再认为目标列上的数据是均匀分布的.CBO会用该列上的直方图的统计信息计算返回结果集的cardinality. 验证直方图对执行计划的影响步骤: 1.创建一张表T1 2.往表中插入倾斜度很高的数据 3.在B字段上创建索引 4.

  • Oracle中获取执行计划的几种方法分析

    1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语句前加explain plan for,此时将生成的执行计划存储到计划表中,语句如下:explain plan for SQL语句然后,在计划表中查询刚刚生成的执行计划,语句如下:select * from table(dbms_xplan.display);注意:Explain plan只生成执行计划,并不会真正

  • Oracle中使用DBMS_XPLAN处理执行计划详解

    DBMS_XPLAN是Oracle提供的一个用于查看SQL计划,包括执行计划和解释计划的包:在以前查看SQL执行计划的时候,我都是使用set autotrace命令,不过现在看来,DBMS_XPLAN包给出了更加简化的获取和显示计划的方式. 这5个函数分别对应不同的显示计划的方式,DBMS_XPLAN包不仅可以获取解释计划,它还可以用来输出存储在AWR,SQL调试集,缓存的SQL游标,以及SQL基线中的语句计划,实现如上的功能,通常会用到一下5个方法: 1.DISPLAY 2.DISPLAY_A

  • ORACLE数据库查看执行计划的方法

    一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等. 很多人以为PL/SQL的执行计划只能看到基数.优化器.耗费等基本信息,其实这个可以在PL/SQL工具里面设置的.可以看到很多其它信息,如下所示 2: 在SQL*PLUS(PL/SQL的命令窗口和SQL窗口均可)下执行下面步骤 复制代码 代码如下: SQL>EXPLAIN PLAN FOR SEL

  • Oracle中基于hint的3种执行计划控制方法详细介绍

    hint(提示)无疑是最基本的控制执行计划的方式了:通过在SQL语句中直接嵌入优化器指令,进而使优化器在语句执行时强制的选择hint指定的执行路径,这种使用方式最大的好处便是方便和快捷,定制度也很高,通常在对某些SQL语句执行计划进行微调的时候我会首选这种方式,不过尽管如此,hint在使用中仍然有很多不可忽视的问题: 使用hint过程中有一些值得注意的细则,首先便是要准确的识别对应的查询块,如果需要使用注释也可以hint中声明:对于使用别名的对象一律使用别名来引用,并且诸如"用户名.对象&quo

  • 达梦数据库获取SQL实际执行计划方法详细介绍

    目录 一.set autotrace trace 二.v$cachepln中获取执行计划 三.ET系统函数 四.dbms_sqltune系统包 五.说明 环境说明: 操作系统:银河麒麟V10 数据库:DM8 相关关键字:DM数据库.SQL实际执行计划 一.set autotrace trace disql下执行set autotrace trace开启AUTOTRACE功能,执行SQL语句,并打印实际的执行计划. SQL> set autotrace trace SQL> select a.e

  • oracle中if/else的三种实现方式详解

    1.标准sql规范 1.单个IF IF v=... THEN END IF; 2.IF ... ELSE IF v=... THEN ELSE t....; END IF; 3.多个IF IF v=... THEN ELSIF v=... THEN t...; END IFL 注意: 多个IF的是'ELSIF' 不是 ' ELSE IF' 2.decode函数 DECODE(VALUE,IF1,THEN1,IF2,THEN2,IF2,THEN2,..,ELSE) 表示如果value等于if1时,

  • oracle中length、lengthb、substr、substrb函数用法介绍

    我记得我曾经在开发form的时候犯过这样一个错误,对于form中的某个字段,对应于数据库中某张表的字段,假设在数据库中这个字段一般也就用到20个汉字的长度,后来我在开发form的时候,设置item类型长度的时候,我惯性的设置成了50byte,想着就算是20个汉字,最多也就占40个byte长度嘛.可是,就因为这一个想当然,结果出现错误了,后来发现数据库字符集编码是utf8,那么应该设置为60.从那以后,每次涉及到给字段设置长度的时候,我都会特别注意下,到底是啥编码. 在oracle中,比较常见的可

  • Android Intent传递对象的两种方法(Serializable,Parcelable)详细介绍

    Android Intent传递对象的两种方法(Serializable,Parcelable)详细介绍 今天要给大家讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是Bundle.putParcelable(Key, Object);当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口,为了让大家更容易理解我还是照常写

  • python中内置库os与sys模块的详细介绍

    目录 os包 sys模块 os包 想要使用os包一样要先导入:import os os包下可以直接调用的函数 下面介绍一下os包中可以直接调用的函数: 例子: 例子: 例子: 注意:os.path.exists()参数可以传绝对路径,也可以传相对路径: 已知一个文件的路径,可以用spilt切割出这个文件名: sys模块 sys模块常用于操作当前的操作系统/环境 sys中常用的函数: 例子: 关于argv我们知道,他可以从程序外部获取参数,我们让他从终端传入参数给程序. 举一个详细的例子介绍: 可

  • PHP四种统计在线人数方式详细介绍

    目录 1 用表统计方式 2 使用 redis 有序集合实现在线人数统计 3 使用 hyperloglog 做统计 4 使用 bitmap 统计 1 用表统计方式 用数据表统计在线人数,这种方式只能用在并发量不大的情况下. 首先我们先新建表:user_login 编辑 user_login 表 模拟用户登录,不存在用户就存入表,存在的则更新登录信息 // 客户端唯一的识别码 $client_id = session()->getId(); //用户是否已存在 $user = DB::table('

  • Oracle中的Connect/session和process的区别及关系介绍

    Session:在计算机中,尤其是在网络应用中,称为"会话". Session:在计算机专业术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间. Connect.session.process的区别: 一个数据库的Connect可以有一个或多个session,同时connect也可以有一个或多个process. 在专业服务器连接方式中,一个session对应一个process,在共享服务器方式中,一个process可以

  • Java中集合List、Set和Map的入门详细介绍

    目录 一.Collection接口 二.List集合 2.1介绍 2.1.1 ArrayList(数组) 2.1.2 Vector(数组实现.线程同步) 2.1.3 LinkList(链表) 2.2 List特性 2.3 List常用方法 2.4 List总结 三.Set集合 3.1介绍 3.2 分类 3.2.1 HashSet(Hash表) 3.2.2 TreeSet(二叉树) 3.2.3 LinkHashSet(HashSet+LinkedHashMap) 四.Map集合 4.1 HashM

  • 基于php上传图片重命名的6种解决方法的详细介绍

    一,适用场景:无法使用从数据库中返回的自增长数字,给上传图片重命名. 这是图片或文件上传的流程决定的.一般图片上传处理过程是,先上传图片到服务器,重命名之后,插入到数据库.也就是说,在数据库中非常容易获得的自增长id,无法用于给上传的图片重命名,来避免文件名称的重复,而采用从数据库中获取最大id加1的方式,增加了数据库连接的次数,不适用于高并发和数据量巨大的情况: 二,常规方案: 1,guid:32 字符十六进制数.格式:GUID 的格式为"xxxxxxxx-xxxx-xxxx-xxxx-xxx

随机推荐