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 个不同的 table
然后加入我的主 table
TD 错误文档中的实际错误翻译建议使用 "USING followed by data parcel"。据我了解,您不能在 UDF 中做所有这些事情
那么除了拆分字符串之外,还有其他方法吗?
我有 40 万个列表中的字符串,我想避免加载到 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.
它不会让我使用拉丁语。我的表是 LATIN,因此它使用导致字符集转换的翻译开销。这里有解决方法吗? (也许自己翻译 UDF 的输出列,这样优化器就不会在连接列上执行此操作。但这在改进方面并不重要,因为优化器无论如何都会选择用较少的行来翻译字符集)
顺便说一句:我在 14.1 上,如下所示
instring
a character or CLOB argument.
If instring is NULL, the STRTOK_SPLIT_TO_TABLE returns NULL.
根据文档 - 我可以为 instring 粘贴一个 CLOB。因此,即使在我的 > 32K 字符串被转换为 CLOB 之后,它也会抛出
EXPLAIN Failed. 3738: String is longer than 31000 characters
最后 ....使用 character_length ('string in D1') 和 (' ditto d2') 我得到 19K。它说 varchar (32000 ) limit for instring,所以想知道为什么拒绝?
Update:我可以 CLOB D1 和 D2 并限制为 2 个字符串方法并偷偷溜出 9134 错误。但是 2 个注意事项仍然存在 -
- 这个 UDF 只喜欢 UNICODE 的 token 。我在令牌中添加了一个 'translation',无论它值多少钱。
当我用这个
测试时,我不太了解 32K 逻辑在这里是如何工作的
sel Character_length ('string here' )
Returns 我的数字 < 32K 所以我的字符串不应该受到 32K 上限的限制
所以在查询的较小部分中使用它可以正常工作。我可以将字符串列表转换为 tables ,让这些加入并提取我感兴趣的 ID 列表,但是当我将组件插入更大的报告时,它吓坏了 - "segementation fault in Local AMP dont re-submit" .. ..
所以我不得不采用另一种方法。
这可能是 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
我可能再次抱有希望,但在列表中使用 STRTOK_SPLIT_TO_TABLE 时,我的列表大于 32K 个字符,它给了我上述错误
EXPLAIN Failed. 3738: String is longer than 31000 characters
我做了什么
拆分字符串并使用 2 STRTOK_SPLIT_TO_TABLE 创建 2 个不同的 table 然后加入我的主 table
TD 错误文档中的实际错误翻译建议使用 "USING followed by data parcel"。据我了解,您不能在 UDF 中做所有这些事情 那么除了拆分字符串之外,还有其他方法吗? 我有 40 万个列表中的字符串,我想避免加载到 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.
它不会让我使用拉丁语。我的表是 LATIN,因此它使用导致字符集转换的翻译开销。这里有解决方法吗? (也许自己翻译 UDF 的输出列,这样优化器就不会在连接列上执行此操作。但这在改进方面并不重要,因为优化器无论如何都会选择用较少的行来翻译字符集)
顺便说一句:我在 14.1 上,如下所示
instring
a character or CLOB argument.
If instring is NULL, the STRTOK_SPLIT_TO_TABLE returns NULL.
根据文档 - 我可以为 instring 粘贴一个 CLOB。因此,即使在我的 > 32K 字符串被转换为 CLOB 之后,它也会抛出
EXPLAIN Failed. 3738: String is longer than 31000 characters
最后 ....使用 character_length ('string in D1') 和 (' ditto d2') 我得到 19K。它说 varchar (32000 ) limit for instring,所以想知道为什么拒绝?
Update:我可以 CLOB D1 和 D2 并限制为 2 个字符串方法并偷偷溜出 9134 错误。但是 2 个注意事项仍然存在 -
- 这个 UDF 只喜欢 UNICODE 的 token 。我在令牌中添加了一个 'translation',无论它值多少钱。
当我用这个
测试时,我不太了解 32K 逻辑在这里是如何工作的sel Character_length ('string here' )
Returns 我的数字 < 32K 所以我的字符串不应该受到 32K 上限的限制
所以在查询的较小部分中使用它可以正常工作。我可以将字符串列表转换为 tables ,让这些加入并提取我感兴趣的 ID 列表,但是当我将组件插入更大的报告时,它吓坏了 - "segementation fault in Local AMP dont re-submit" .. .. 所以我不得不采用另一种方法。
这可能是 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