2015/7/16

[Teradata] 3577 : Row Size or Sort Key Size overflow

最近在 Teradata 上,當使用者想要撈大量資料的時候,就會遇到 Teradata ODBC 3577 : Row size or Sort Key size overflow 的錯誤。一開始完全沒有頭緒,所以還是上網請教最有智慧的谷歌大神,果然谷歌大神的聰明才智是無人能比。

原來是因為在 Teradata 裡面,進行 SQL select 的時候,select 出來單一筆的資料長度不能超過 64 KB,而且這邊的資料長度指的不是實際資料長度,而是這些欄位的定義長度。也就是說,如果你開了一個欄位 VARCHAR (1024),但是裡面存的資料只有 VARCHAR(2),這樣子的話,定義長度就是 1024,而不是只有 2,因此,如果當初設計 table schema 沒有弄好,就會不小心踩到這樣的問題。

另外,要注意一件事,欄位的宣告長度,通常是以 ASCII or LATIN 的編碼來做計算。也就是說,如果你的資料庫 session 是用 UTF8 編碼,則欄位長度要乘上 3 倍。如果是 UTF16 編碼,則欄位長度要乘上 2 倍。舉例一個 VARCHAR(100) 的欄位,在 ASCII 編碼時,宣告長度就是 100;但是在 UTF8 編碼的情況,宣告長度則變成 300;以此類推,UTF16 的宣告長度則變成 200。

所以,遇到 Teradata ODBC 3577 : Row size or Sort Key size overflow 的時候,可以試試下面幾種方法,看看哪一種方法比較適合。

  1. 試著拿掉一些不要的欄位,有的時候會有 select * 的情況,把一些沒必要撈出來的長字串欄位都一起撈出來了,這樣也浪費 resource 跟 performance 在處理資料。
  2. 如果是因為自己資料庫 session 的編碼設定是用 UTF8 或 UTF16,可以先試著將編碼轉成 ASCII,如果可以過,而且沒有特殊字元呈現的問題,那就可以這樣先解決。不過千萬要注意,把資料庫 session 的 CHARSET 從 UTF8 改為 ASCII,可能會造成特殊語系的文字變亂碼。
  3. 再來就是可以找出宣告長度過長的欄位,把資料長度 cast 變成長度較短的 VARCHAR 或是 CLOB,試看看是否足夠解決這個長度過長的問題。

最後我們是找出我們撈出來的資料欄位,有幾個欄位存放的資料長度根本就不到 100 (而且也根本不可能超過 100),但是定義長度卻是 1024,所以在不動 table schema 的情況之下,就是直接把這些欄位 cast as VARCHAR(100) 就可以解決這樣的問題了。不過如果在確定欄位真的不會存放這麼長資料的情況,最好還是直接改 database 的 table schema 比較算是正解。

另外順道一提,Teradata 在 宣告長度 64 KB 的長度限制之下,一筆資料最多可以撈出 2048 個欄位喔。

參考網頁:
DBQL SQLTextInfo 3577: row size or sort key size overflow
3577   Row size or Sort Key size overflow.
Teradata SQLA: Row size or Sort Key size overflow

沒有留言:

張貼留言