【问题标题】:Hidden features in OracleOracle 中的隐藏特性
【发布时间】:2010-09-27 17:31:26
【问题描述】:

我很喜欢关于hidden features in sql server 的回答和问题

您能告诉我们关于 Oracle 的哪些信息?
隐藏的表、...的内部工作原理、秘密存储的过程、具有良好实用程序的包...

【问题讨论】:

    标签: oracle oracleinternals


    【解决方案1】:

    由于 Apex 现在是每个 Oracle 数据库的一部分,即使您不使用 Apex,这些 Apex 实用程序功能也很有用:

    SQL> declare
      2    v_array apex_application_global.vc_arr2;
      3    v_string varchar2(2000);
      4  begin
      5  
      6    -- Convert delimited string to array
      7    v_array := apex_util.string_to_table('alpha,beta,gamma,delta', ',');
      8    for i in 1..v_array.count
      9    loop
     10      dbms_output.put_line(v_array(i));
     11    end loop;
     12  
     13    -- Convert array to delimited string
     14    v_string := apex_util.table_to_string(v_array,'|');
     15    dbms_output.put_line(v_string);
     16  end;
     17  /
    alpha
    beta
    gamma
    delta
    alpha|beta|gamma|delta
    
    PL/SQL procedure successfully completed.
    

    【讨论】:

    • 我喜欢这两个函数:'已经看到我们的 dbas 和 stored-proc-devs 连接字符串很多次了......
    【解决方案2】:

    “全表扫描并不总是坏的。索引并不总是好的。”

    当您根据每个工作单元(通常是每个逻辑读取)访问的行数来衡量时,基于索引的访问方法在读取行方面的效率低于完全扫描。然而,许多工具会将全表扫描解释为效率低下的标志。

    举个例子,您正在从一个发票表中读取几百张发票,并在一个小型查找表中查找一种付款方式。使用索引来探测每张发票的查找表可能意味着每张发票需要三个或四个逻辑 io。但是,完整扫描查找表以准备从发票数据进行散列连接可能只需要几次逻辑读取,并且散列连接本身将在内存中完成几乎没有任何成本。

    然而,许多工具会看到这个并看到“全表扫描”,并告诉您尝试使用索引。如果你这样做了,那么你可能刚刚调整了你的代码。

    顺便说一句,如上例所示,过度依赖索引会导致“Buffer Cache Hit Ratio”上升。这就是为什么 BCHR 作为系统效率的预测指标大多是无稽之谈。

    【讨论】:

      【解决方案3】:

      基数提示大多没有记录。

       explain plan for
       select /*+ cardinality(@inner 5000) */ *
       from   (select /*+ qb_name(inner) */ * from dual)
       /
       select * from table(dbms_xplan.display)
       /
       --------------------------------------------------------------------------
       | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
       --------------------------------------------------------------------------
       |   0 | SELECT STATEMENT  |      |  5000 | 10000 |     2   (0)| 00:00:01 |
       |   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
       --------------------------------------------------------------------------
      

      【讨论】:

      • 基数也是一个很好的提示,因为它通常会修复您计划的其余部分,并且在将来很容易理解。
      • 基数提示对于表函数来说是关键...amolinaro 在这里丢掉一些知识:lazydba.com/oracle/0__116173.html
      【解决方案4】:

      Buffer Cache Hit Ratio 作为系统效率的预测指标实际上毫无意义

      【讨论】:

        【解决方案5】:

        您可以使用闪回查询查看上次的表数据,但有一定的限制。

        Select *
          from my_table as of timestamp(timestamp '2008-12-01 15:21:13')
        

        11g 具有一个全新的功能集,可以更稳健地保留历史变化。

        【讨论】:

          【解决方案6】:

          频繁重建索引几乎总是浪费时间。

          【讨论】:

            【解决方案7】:

            wm_concat 像 MySql group_concat 一样工作,但它没有记录。

            有数据:

            -car-   -maker-
            Corvette Chevy
            Taurus   Ford
            Impala   Chevy
            Aveo     Chevy
            
            select wm_concat(car) Cars, maker from cars
            group by maker
            

            给你:

            -Cars-                   -maker-
            Corvette, Impala, Aveo   Chevy
            Taurus                   Ford
            

            【讨论】:

            • 我认为您可能需要 Oracle 10,但我不是 100% 确定
            • 从 Oracle 11g2 开始,您可能不应该再使用 wm_concat,因为有一个成熟的 LISTAGG() 有序聚合(和分析)函数
            【解决方案8】:

            【讨论】:

            • 很酷,虽然如果你不愿意在生产中使用它,那有什么好处?
            • 对于任何未记录或隐藏的功能都是如此。不支持。
            【解决方案9】:

            我刚刚发现了伪列 Ora_rowSCN。如果您不为此设置表格,则此 pcolumn 将为您提供块 SCN。这对于紧急情况非常有用,“哦,废话,我没有对此表进行审计,想知道是否有人从昨天开始更改了数据。”

            但更好的是,如果您在 Rowdependecies ON 的情况下创建表。这会将最后一次更改的 SCN 放在每一行上。这将帮助您避免“丢失编辑”问题,而不必在查询中包含每一列。

            IOW,当您的应用抓取一行进行用户修改时,还要选择 Ora_rowscn。然后,当您发布用户的编辑内容时,除了 where 子句中的唯一键之外,还包括 Ora_rowscn = v_rscn。如果有人在您抓取后触摸了该行,也就是丢失了编辑,则更新将匹配零行,因为 ora_rowscn 将发生变化。

            太酷了。

            【讨论】:

              【解决方案10】:

              如果您在DBA_USERS 上获得PASSWORD 列的值,您可以在不知道密码的情况下备份/恢复密码:

               ALTER USER xxx IDENTIFIED BY VALUES 'xxxx';
              

              【讨论】:

              • 11g 更改了它,您不能再使用 DBA_USERS 中的值。但是,您可以使用 DBMS_METADATA(在 9iR1 中重新添加)为您生成 DDL:coskan.wordpress.com/2009/03/11/…
              【解决方案11】:

              绕过缓冲区缓存并使用直接路径读取直接从磁盘读取。

              alter session set "_serial_direct_read"=true;
              

              导致表空间 (9i) 或快速对象 (10g+) 检查点,因此在繁忙的 OLTP 系统上要小心。

              【讨论】:

                【解决方案12】:

                http://awads.net/wp/tag/undocumented/ 上的更多无证资料

                警告:使用风险自负。

                【讨论】:

                  【解决方案13】:

                  我不知道这算不算隐藏,但是当我看到这种快速查看您正在调整的 SQL 语句发生了什么的方式时,我非常高兴。

                  SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM DUAL;
                  
                  SELECT * FROM TABLE(dbms_xplan.display_cursor( NULL, NULL, 'RUNSTATS_LAST'))
                  ;
                  
                  PLAN_TABLE_OUTPUT
                  -----------------------------------------------------
                  SQL_ID  5z36y0tq909a8, child number 0
                  -------------------------------------
                  SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM DUAL
                  
                  Plan hash value: 272002086
                  
                  ---------------------------------------------------------------------------------------------
                  | Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
                  ---------------------------------------------------------------------------------------------
                  |   1 |  TABLE ACCESS FULL| DUAL |      1 |      1 |      1 |00:00:00.02 |       3 |      2 |
                  ---------------------------------------------------------------------------------------------
                  
                  
                  12 rows selected.
                  

                  地点:

                  • E-Rows 是估计的行数。
                  • A-Rows 是实际行。
                  • A-Time 是实际时间。
                  • Buffers 是实际的缓冲区。

                  如果估计的计划与实际执行相差几个数量级,你就知道你遇到了问题。

                  【讨论】:

                    【解决方案14】:

                    不是隐藏功能,但细粒度访问控制 (FGAC),也称为行级安全性,是我过去使用过的东西,它的实施效率给我留下了深刻的印象。如果您正在寻找能够保证您可以控制向具有不同权限的用户公开行的粒度的东西 - 无论用于查看数据的应用程序(SQL*Plus 以及您的 Web 应用程序) - 那么这是一个宝石.

                    内置全文索引的文档更广泛,但由于其稳定性仍然很突出(只需尝试对 MS-SQL 和 Oracle 上的类似数据样本运行全文索引列的完整重新索引,您就会看到速度差异)。

                    【讨论】:

                      【解决方案15】:

                      【讨论】:

                      • 这不是隐藏功能。它记录在 SQL 参考指南中。
                      【解决方案16】:

                      Snapshot 表。也可以在 Oracle Lite 中找到,对于滚动您自己的复制机制非常有用。

                      【讨论】:

                      • 你的意思是物化视图吗?
                      • 如果您将物化视图移动到另一个数据库并添加一种机制来跟踪其中发生的所有更改(添加、更新和删除),然后重现所有这些更改回到原始源数据库中。
                      【解决方案17】:

                      @Peter

                      您实际上可以在 TOAD 中绑定“Cursor”类型的变量,然后在您的语句中使用它,它会在结果网格中显示结果。

                      exec open :cur for select * from dual;
                      

                      【讨论】:

                        【解决方案18】:

                        问:如何从 TOAD 调用带游标的存储?

                        A:例如,更改为您的光标、包名和存储的过程名称

                        declare cursor PCK_UTILS.typ_cursor;  
                        
                        begin   
                            PCK_UTILS.spc_get_encodedstring(  
                                'U',  
                                10000002,  
                                null,  
                                'none',  
                                cursor);  
                        end;
                        

                        【讨论】:

                        • 这看起来很酷。但我没有完全理解。您是说如果您有一个返回引用游标的过程,那么您很难在 Toad 中显示它?
                        • 是的!使用此代码,您可以使用引用游标调用存储作为输出。或许您也可以在下一步轻松地遍历记录……
                        【解决方案19】:

                        Model Clause(适用于 Oracle 10g 及更高版本)

                        【讨论】:

                          【解决方案20】:

                          WM_CONCAT 用于字符串聚合

                          【讨论】:

                            【解决方案21】:

                            Scalar subquery caching 是 Oracle 中最令人惊讶的特性之一

                            -- my_function is NOT deterministic but it is cached!
                            select t.x, t.y, (select my_function(t.x) from dual)
                            from t
                            
                            -- logically equivalent to this, uncached
                            select t.x, t.y, my_function(t.x) from t
                            

                            上面的“缓存”子查询对于 t.x 的每个唯一值仅计算一次 my_function(t.x)。如果您有相同t.x 值的大分区,这将极大地加快您的查询速度,即使my_function 声明为DETERMINISTIC。即使是DETERMINISTIC,您也可以保护自己一个可能很昂贵的 SQL -> PL/SQL 上下文切换。

                            当然,如果my_function不是确定性函数,那么这可能会导致错误的结果,所以要小心!

                            【讨论】:

                              猜你喜欢
                              • 2011-03-19
                              • 1970-01-01
                              • 1970-01-01
                              • 2010-11-07
                              • 2010-09-15
                              • 2010-11-07
                              • 2010-09-22
                              • 2010-10-31
                              • 2011-01-30
                              相关资源
                              最近更新 更多