【发布时间】:2011-08-23 20:15:38
【问题描述】:
我遇到了一个棘手的 SQL 查询问题,我希望能提供一个优雅的解决方案。我试图避免 32 个左外连接到同一个表。
数据库是 Teradata。
我有一个包含 1400 万条记录和 33 列的表。主键(我们称它为 Trans_Id)和 32 个编码字段(我们称它们为 encoded_1 ... encoded_32)。像这样的:
CREATE SET TABLE BigTable ,NO FALLBACK , NO BEFORE JOURNAL, NO AFTER JOURNAL, CHECKSUM = DEFAULT
(
TRANS_ID VARCHAR(20) CHARACTER SET LATIN NOT CASESPECIFIC,
ENCODED_1 VARCHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC,
ENCODED_2 VARCHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC,
ENCODED_3 VARCHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC,
...
ENCODED_32 VARCHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC )
PRIMARY INDEX ( TRANS_ID );
我还有一个包含编码/解码值的表。假设这张表有 100 条记录。
CREATE SET TABLE LookupTable ,NO FALLBACK , NO BEFORE JOURNAL, NO AFTER JOURNAL, CHECKSUM = DEFAULT
(
UNIQ_PK { just random numbers }
ENCODED_VAR VARCHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC,
DECODED_DESC VARCHAR(50) CHARACTER SET LATIN NOT CASESPECIFIC)
PRIMARY INDEX ( UNIQ_PK );
我想避免像这样讨厌的连接(我使用省略号而不是显示所有 32 个外连接):
SELECT
TRANS_ID
, a.ENCODED_1
, b1.DECODED_DESC DECODED_DESC_1
, a.ENCODED_2
, b2.DECODED_DESC DECODED_DESC_2
...
, a.ENCODED_31
, b31.DECODED_DESC DECODED_DESC_31
, a.ENCODED_32
, b32.DECODED_DESC DECODED_DESC_32
FROM BigTable a
LEFT OUTER JOIN LookupTable b1 ON a.ENCODED_1 = b1.ENCODED
LEFT OUTER JOIN LookupTable b2 ON a.ENCODED_2 = b1.ENCODED
...
LEFT OUTER JOIN LookupTable b31 ON a.ENCODED_31 = b31.ENCODED
LEFT OUTER JOIN LookupTable b32 ON a.ENCODED_32 = b32.ENCODED
任何帮助将不胜感激。我感觉外部加入 14M 记录 32 次不是这样做的有效方法!
【问题讨论】:
-
" 感觉外部加入 14M 记录 32 次不是这样做的有效方法!" - 慢吗?
-
如果第二个表太小(100 条记录)以至于整个表都可以保存在内存中,那么我看不出有什么方法可以让它变得更好。看起来很糟糕,但真的很慢吗?
-
您能否详细说明您要达到的目标?你真的要返回 1400 万条记录吗?您正在“左连接”,因为 BigTable 中的某些字段的值不是您的 LookupTable?
-
为什么要全部查询?我的意思是,你想让所有 1400 万条记录一起查看吗?
-
它不是特别慢(但它很昂贵 - 32 个全安培,全行扫描)。我并不关心查询的速度,因为我只是担心敲出来有多讨厌。每列都有唯一的名称,没有模式,我没有实习生来做。我需要用于报告和分析的解码文本 - 来自 14M 的样本(和重新采样)将定期采集和分发。
标签: sql join query-optimization teradata