AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 25494
Accepted
rfusca
rfusca
Asked: 2012-10-06 05:28:54 +0800 CST2012-10-06 05:28:54 +0800 CST 2012-10-06 05:28:54 +0800 CST

多列扩展统计、NLS_SORT 和 NLS_COMP、CHAR 列以及我存在的祸根

  • 772

这是这个问题的结果。
所以我正在处理一个看起来像这样的查询:

select count(*) 
from table1 
where col1 = 123 
and col2 = '1';

问题是这样的: col2被定义为一个CHAR(1)和所有会话集NLS_SORT = 'BINARY_CI'和NLS_COMP = 'LINGUISTIC'。(col1是一NUMBER列。)

首先,在没有为会话启用 NLS 设置的情况下,定义一个多列扩展统计(col1,col2)可以正常工作并产生适当的基数。

但是对于NLS_SORT = 'BINARY_CI'and NLS_COMP = 'LINGUISTIC',它不使用扩展统计信息。我相信它很像一个索引和 NLS 设置——我们必须用(NLSSORT("COL2",'nls_sort=''BINARY_CI''')).

因此,我在("COL1", (NLSSORT("COL2",'nls_sort=''BINARY_CI''')). 但它仍然不起作用(但定义相同的索引将起作用)。

在谓词信息中,它显示在启用 NLS 设置的情况下,col2 = '1'转换为: NLSSORT(INTERNAL_FUNCTION(col2),'nls_sort=''BINARY_CI''')=HEXTORAW('3100')。我相信这INTERNAL_FUNCTION()是由于col2被定义为CHAR(1)。我无法改变这一点。

根据我的条件,如何为这些列创建多列扩展统计列组?

oracle-11g-r2
  • 2 2 个回答
  • 1409 Views

2 个回答

  • Voted
  1. Best Answer
    Jack Douglas
    2012-10-06T09:09:41+08:002012-10-06T09:09:41+08:00

    我认为您在这里唯一的选择是“滚动自己的”伪多列统计信息——因为无法在 Virtual Columns 上创建扩展统计信息。例如:

    试验台:

    drop table table1;
    create table table1(col1 integer, col2 char(1));
    insert into table1(col1,col2) select mod(level,10), '0' from dual connect by level<=1000;
    insert into table1(col1,col2) select mod(level,10)+100, '1' from dual connect by level<=1000;
    commit;
    select count(*) from table1 where col1=1 and col2='0';
    /*
    COUNT(*)
    --------
         100
    */
    

    首先尝试使用正常直方图(注意“行”估计是“差”):

    exec dbms_stats.gather_table_stats(null,'TABLE1');
    explain plan for select * from table1 where col1=1 and col2='0';
    select * from table(dbms_xplan.display);
    /*
    ----------------------------------------------------------------------------
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |        |    50 |   250 |    59   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| TABLE1 |    50 |   250 |    59   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("COL1"=1 AND "COL2"='0')
    */
    

    现在创建虚拟串联列(注意“行”估计是“好”):

    alter table table1 add col21 generated always as (col2||col1); 
    exec dbms_stats.gather_table_stats(null,'TABLE1');
    explain plan for select * from table1 where col21='01';
    select * from table(dbms_xplan.display);
    /*
    ----------------------------------------------------------------------------
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |        |   100 |   900 |    59   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| TABLE1 |   100 |   900 |    59   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("COL21"='01')
    */
    

    最后重复 NLS 参数集:

    alter session set nls_sort='BINARY_CI';
    alter session set nls_comp='LINGUISTIC';
    explain plan for select * from table1 where col21='01';
    select * from table(dbms_xplan.display);
    /*
    ----------------------------------------------------------------------------
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |        |   100 |   900 |    59   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| TABLE1 |   100 |   900 |    59   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter(NLSSORT("COL21",'nls_sort=''BINARY_CI''')=HEXTORAW('303100
                  ') )
    */
    
    • 2
  2. Jack Douglas
    2012-10-06T10:14:05+08:002012-10-06T10:14:05+08:00

    没有索引:

    drop table table1;
    create table table1(col1 integer, col2 char(1));
    insert into table1(col1,col2) select mod(level,10), '0' from dual connect by level<=1000;
    insert into table1(col1,col2) select mod(level,10)+100, '1' from dual connect by level<=1000;
    exec dbms_stats.gather_table_stats(null,'TABLE1');
    explain plan for select * from table1 where col1=1 and col2='0';
    select * from table(dbms_xplan.display);
    /*
    ----------------------------------------------------------------------------
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |        |    50 |   250 |    59   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| TABLE1 |    50 |   250 |    59   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("COL1"=1 AND "COL2"='0')*/
    

    带索引:

    alter session set nls_sort='BINARY_CI';
    alter session set nls_comp='LINGUISTIC';
    create index i_table1 on table1(col1,nlssort("COL2",'nls_sort=''BINARY_CI'''));
    exec dbms_stats.gather_table_stats(null,'TABLE1');
    explain plan for select * from table1 where col1=1 and col2='0';
    select * from table(dbms_xplan.display);
    /*
    ----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |          |   100 |   800 |     5   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TABLE1   |   100 |   800 |     5   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | I_TABLE1 |   100 |       |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("COL1"=1 AND NLSSORT(INTERNAL_FUNCTION("COL2"),'nls_sort=''BINARY_
                  CI''')=HEXTORAW('3000') )
    */
    
    • 1

相关问题

  • 数据泵导出如何在 Windows 上限制其资源使用?

  • 数据泵导出如何在 Linux 上限制其资源使用?

  • 为什么操作系统身份验证被认为是 Oracle 数据库的低安全性?

  • 您如何对 Oracle 数据库更改进行版本控制?

  • 有没有办法允许代理连接在公共数据库链接中使用通过的身份验证?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve