小心NLS_SORT和NLS_COMP的设置成为性能杀手

NLS_SORT和NLS_COMP是Oracle两个初始化参数。顾名思义,NLS_SORT和NLS_COMP是设置排序和比较的方式。通过设置这两个参数可以实现自定义的排序和比较的方式。设置这两个参数的值可以在数据库创建的时候指定,也可以通过Alter Session语句来修改。如果是在创建数据库的时候设定,那么是不能再修改的,并在所有的Session中起作用。但是我们也通过Alter Session命令临时改变这两个参数的值,在会话中临时使用一种特定的排序和比较的方式。要改变所有的会话的排序和比较的方式,我们也可以通过修改注册表的方式来达到目的,如果系统采用的多层体系架构,并且所有的逻辑层代码都部署在相同的应用程序服务器(如IIS)上的。

查看会话中这两个参数值,我们可以使用如下的查询语句:

select * from NLS_SESSION_PARAMETERS;

PARAMETER                                                     VALUE
------------------------------------------------------------ --------------------------------------------------------------------------------
NLS_LANGUAGE                                                  SIMPLIFIED CHINESE
NLS_TERRITORY                                                 CHINA
NLS_CURRENCY                                                  RMB
NLS_ISO_CURRENCY                                              CHINA
NLS_NUMERIC_CHARACTERS                                        .,
NLS_CALENDAR                                                  GREGORIAN
NLS_DATE_FORMAT                                               DD-MON-RR
NLS_DATE_LANGUAGE                                             SIMPLIFIED CHINESE
NLS_SORT                                                      BINARY
NLS_TIME_FORMAT                                               HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT                                          DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT                                            HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT                                       DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY                                             RMB
NLS_COMP                                                      BINARY
NLS_LENGTH_SEMANTICS                                          BYTE
NLS_NCHAR_CONV_EXCP                                           FALSE

    在我们的一个项目中,客户突然要求所有的查询都大小写无关,但是由于在创建数据库的时候没有设置两个参数的值,在没一个查询语句中去执行Alter Session语句来设置这两个值又显得十分的笨拙和荒唐,所以我们采用修改注册表的方式来达到这个目的,但是有一天客户突然报告原来运行的很快的程序,突然变得特别的慢。慢的表征是用户创建一个比较大的变更单,变更单里包含了几千条变更记录。从出错的信息中我分析出是超时的原因,超时也就意味者系统长时间无法响应或者事务长时间无法完成。

    生产环境出错是非常致命的。根据用户提供的数据我们马上做了测试,结果表明是在几秒钟就迅速完成了!用户将数据导出到另外一台测试服务器上运行,还是相同的结果,远程指导用户直接在测试库上运行存储过程,结果第二天用户告诉我,执行完该存储过程整整花了20多个小时!!

    又是一番针对存储过程的分析和优化,针对服务器设置的各个方面的设置的分析,但是问题仍然得不到解决,百思不得其解。又是一天过去了,真让人心焦啊。晚上在家里查找资料的时候,用户在MSN上告诉我,问题得到解决了,我一惊,是怎么解决的?用户告诉我,将在注册表中修改了NLS_SORT和NLS_COMP的注册项删除掉,重新启动IIS,程序运行的速度就一下子提高了,确实就是在几秒钟内完成的!!

在Oracle官方提高的文档中,确实提到如果改变了NLS_SORT和NLS_COMP的缺省值,可能会对性能产生影响但是我没有想到会有这么大的影响。在Oracle官方文档中对NLS_SORT是这样描述的。

NLS_SORT

PropertyDescription
Parameter typeString
SyntaxNLS_SORT = { BINARY | linguistic_definition }
Default valueDerived from NLS_LANGUAGE
ModifiableALTER SESSION
Range of valuesBINARY or any valid linguistic definition name

NLS_SORT specifies the collating sequence for ORDER BY queries.

  • If the value is BINARY, then the collating sequence for ORDER BY queries is based on the numeric value of characters (a binary sort that requires less system overhead).

  • If the value is a named linguistic sort, sorting is based on the order of the defined linguistic sort. Most (but not all) languages supported by the NLS_LANGUAGE parameter also support a linguistic sort with the same name.

    Note:

    Setting NLS_SORT to anything other than BINARY causes a sort to use a full table scan, regardless of the path chosen by the optimizer. BINARY is the exception because indexes are built according to a binary order of keys. Thus the optimizer can use an index to satisfy the ORDER BY clause when NLS_SORT is set to BINARY. If NLS_SORT is set to any linguistic sort, the optimizer must include a full table scan and a full sort in the execution plan.

You must use the NLS_SORT operator with comparison operations if you want the linguistic sort behavior.

 

根据上文中标红部分的注视,如果NLS_SORT不是设置为"Binary",那么就会引起全表扫描,是不会使用索引的,在我们的系统中变更单涉及到的数据都是数据庞大的表,如果不使用到索引,查询的效率不受到影响才怪呢!

NLS_COMP

PropertyDescription
Parameter typeString
SyntaxNLS_COMP = { BINARY | LINGUISTIC | ANSI }
Default valueBINARY
ModifiableALTER SESSION
BasicNo

NLS_COMP specifies the collation behavior of the database session.

Values:

  • BINARY

    Normally, comparisons in the WHERE clause and in PL/SQL blocks is binary unless you specify the NLSSORT function.

  • LINGUISTIC

    Comparisons for all SQL operations in the WHERE clause and in PL/SQL blocks should use the linguistic sort specified in the NLS_SORT parameter. To improve the performance, you can also define a linguistic index on the column for which you want linguistic comparisons.

  • ANSI

    A setting of ANSI is for backwards compatibility; in general, you should set NLS_COMP to LINGUISTIC

根据标红的部分,要提高性能可以在需要比较的列上建立一个linguistic index

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ORACLE中的数据类型.doc 当你在数据库中创建数据表的时候,你需要定义表中所有字段的类型。ORACLE有许多种数据类型以满足你的需要。数据类型大约分为:character, number, date, LOB, 和RAW等类型。虽然ORACLE8i也允许你自定义数据类型,但是它们是最基本的数据类型。在下面的文章中你将了解到他们在oracle 中的用法、限制以及允许值。 l Character 数据类型 Character 数据类型用来存储字母数字型数据。当你在oracle 中定义一个character 数据时,通常需要制定字段的长度,它是该字段的最大长度。ORACLE提供以下几种character 数据类型: CHAR(<size>) CHAR数据类型是一种有固定长度和最大长度的字符串。存储在数据类型为CHAR字段中的数据将以空格的形式补到最大长度。长度定义在1——2000字节之间。 当你创建一个CHAR型字段,数据库将保证在这个字段中的所有数据是定义长度,如果某个数据比定义长度短,那么将用空格在数据的右边补到定义长度。如果长度大于定义长度将会触发错误信息。 VARCHAR(<size>) varchar型数据是varchar2型数据的快照。 VARCHAR2(<size>) varchar2数据类型是一种可变长度的、有最大长度的字母数字型数据。Varchar2类型的字段长度可以达到4000字节,Varchar2类型的变量长度可以达到32676字节。 一个空的varchar2(2000)字段和一个空的varchar2(2)字段所占用的空间是一样的。 NCHAR(<size>) 和 NVARCHAR2(<size>) NCHAR(<size>) 和 NVARCHAR2(<size>)数据类型分别与CHAR(<size>) 和 VARCHAR2(<size>)类型是相同的,只不过它们用来存储NLS(National Language Support)数据。 LONG LONG 数据类型是一个遗留下来的而且在将来不会被支持的数据类型。它将被LOB(Large Object)数据类型所代替。 比较规则 Varchar2和char数据类型根据尾部的空格有不同的比较规则。对Char型数据,尾部的空格将被忽略掉,对于Varchar2型数据尾部带空格的数据排序比没有空格的要大些。比如: Char 型数据: ‘YO’=‘YO ’ Varchar2型数据: ‘YO’<’YO ’

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值