繁体   English   中英

Teradata SQL性能调整:STRTOK_SPLIT_TO_TABLE:EXPLAIN失败。 3738:字符串长于31000个字符

[英]Teradata SQL Performance Tuning: STRTOK_SPLIT_TO_TABLE: EXPLAIN Failed. 3738: String is longer than 31000 characters

我可能再次希望不对,但是在列表中使用STRTOK_SPLIT_TO_TABLE时,列表中我的列表> 32K字符,则出现上述错误

EXPLAIN Failed. 3738:  String is longer than 31000 characters

我做了什么

拆分字符串并使用2个STRTOK_SPLIT_TO_TABLE创建2个不同的表,然后加入我的主表

TD错误文档中的实际错误转换建议使用“使用后跟数据包”。 据我了解,您无法在UDF中完成所有这些工作,因此,除了拆分字符串以外,还有其他方法吗? 我有400K列表中的字符串,我希望避免将其加载到VT,因为这似乎有其自身的开销成本,因此使用此功能,但从未成功。


    EXPLAIN 
SELECT  COL1 
FROM    DB.TB1 , ( 
SELECT  TOKEN2 
FROM    TABLE ( STRTOK_SPLIT_TO_TABLE( 1 , '123456,123456,43456,......20K Long string' ,
','  ) 
RETURNS ( OUTKEY INT , TOKENNUM INT , TOKEN2 VARCHAR ( 20 ) CHARACTER 
SET unicode ) ) DD ) D2 ,


 ( 
SELECT  TOKEN1
FROM    TABLE ( STRTOK_SPLIT_TO_TABLE( 1 , '123456,123456,43456.....20K long string' ,','  ) 
RETURNS ( OUTKEY INT , TOKENNUM INT , TOKEN1 VARCHAR ( 20 ) CHARACTER 
SET unicode ) ) DD ) D1 

WHERE   SUBSTR ( TB1.COL2 , 21 , 9 ) = d2.token2 

or  SUBSTR ( TB1.COL2 , 21 , 9 ) = d1.token1
GROUP BY 1 ;


/* the same logic can be re-wrritten 
   with a UNION  or  Where EXISTS logic  
      but focus's on that UDF */

所以总结一下....

  • 我必须进一步拆分字符串长度为较小的位。 两个是不够的。 当字符串真的足够值得运行拆分字符串UDF时,如何利用UDF功能? 这是我使用较小的字符串时遇到的错误。 我的explain会顺利进行,因为UDF会抛出此错误

     Query Failed. 9134: STRTOK: Input string exceeded the max. allowed string length. 
  • 它不会让我使用拉丁文。 我的表是拉丁文,因此它使用转换开销,导致字符集转换。 这里有解决方法吗? (也许您自己翻译了UDF的输出列,所以优化程序不会在join列上执行此操作。但是,就改进而言,这无关紧要,因为优化程序会选择以较少的行来转换char集)

顺便说一句:我在14.1和以下

    instring
a character or CLOB argument.
If instring is NULL, the STRTOK_SPLIT_TO_TABLE returns NULL.

从文档-我可以为字符串插入CLOB。 因此,即使在我的> 32K字符串被转换为CLOB之后,它也会抛出

EXPLAIN Failed. 3738:  String is longer than 31000 characters

最后...使用character_length('D1中的字符串')和('ditto d2')得到19K。 它说varchar(32000)限制为instring,所以想知道为什么拒绝?

更新 :我可以CLOB D1和D2并限制为2字符串方法,并溜走了9134错误。 但是仍有2个警告-

  • 此UDF仅喜欢UNICODE作为令牌。 我为令牌添加了“翻译”功能,无论其价值多少。
  • 当我用它测试时,我不太了解32K逻辑在这里如何工作

    sel Character_length ('string here' )

    返回一个小于32K的数字,因此我的字符串不应受到32K上限的限制

因此,在查询的较小部分中使用此方法效果很好。 我可以将字符串列表转换为表格,进行连接,然后拉出我感兴趣的ID列表,但是当我将组件插入更大的报表时,它却怪异地出现了“本地AMP中的分段错误,请勿重新提交”。 ...所以我不得不调整另一种方法。

这可能是teradata UDF中的错误,尽管instring长度小于32K,它仍会拒绝它。

sel char_length ('string 32K or less' ) will give o/p 
31890 

当我在这里使用

SELECT  COL1 
FROM    DB.TB1 , ( 
SELECT  TOKEN2 
FROM    TABLE ( STRTOK_SPLIT_TO_TABLE( 1 , '123456,123456,43456,......32K Long string' ,
','  ) 
RETURNS ( OUTKEY INT , TOKENNUM INT , TOKEN2 VARCHAR ( 20 ) CHARACTER 
SET unicode ) ) DD ) D2 

它将失败,并且失败点在32K的一半左右。 > 16K个字符将失败。 但是使用CLOB使其可以工作除错误之外,我无法提供其他解释

SELECT  COL1 
FROM    DB.TB1 , ( 
SELECT  TOKEN2 
FROM    TABLE ( STRTOK_SPLIT_TO_TABLE( 1 , '123456,123456,43456,......32K Long string' ( CLOB)  ,
','  ) 
RETURNS ( OUTKEY INT , TOKENNUM INT , TOKEN2 VARCHAR ( 20 ) CHARACTER 
SET unicode ) ) DD ) D2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM