我正在移植一个创建CROSS JOIN
两个表的 MASSIVE 的进程。结果表包含 15m 条记录(看起来该过程与 2600 行表和 12000 行表进行 30m 交叉连接,然后进行一些必须将其分成两半的分组)。行相对较窄 - 只有 6 列。它已经运行了5个小时,没有完成的迹象。我只是注意到已知商品和我对交叉连接的期望之间的计数差异,所以我的输出没有分组或重复数据删除,这将使决赛桌减半 - 但这似乎仍然不会完成任何时间很快。
首先,如果可能的话,我将寻求从流程中消除该表 - 显然它可以通过单独加入两个表来替换,但现在我无法看到它使用的其他任何地方。
但是鉴于现有的流程可以做到(在更短的时间内,在功能不太强大的机器上,使用 FOCUS 语言),是否有任何选项可以提高CROSS JOIN
SQL Server(2005)中大 s 的性能(硬件不是真正的选项,这个盒子是 64 位 8 路 32 GB RAM)?
细节:
它是在 FOCUS 中以这种方式编写的(我试图产生相同的输出,它是 SQL 中的 CROSS JOIN):
JOIN CLEAR *
DEFINE FILE COSTCENT
WBLANK/A1 = ' ';
END
TABLE FILE COSTCENT
BY WBLANK BY CC_COSTCENT
ON TABLE HOLD AS TEMPCC FORMAT FOCUS
END
DEFINE FILE JOINGLAC
WBLANK/A1 = ' ';
END
TABLE FILE JOINGLAC
BY WBLANK BY ACCOUNT_NO BY LI_LNTM
ON TABLE HOLD AS TEMPAC FORMAT FOCUS INDEX WBLANK
JOIN CLEAR *
JOIN WBLANK IN TEMPCC TO ALL WBLANK IN TEMPAC
DEFINE FILE TEMPCC
CA_JCCAC/A16=EDIT(CC_COSTCENT)|EDIT(ACCOUNT_NO);
END
TABLE FILE TEMPCC
BY CA_JCCAC BY CC_COSTCENT AS COST CENTER BY ACCOUNT_NO
BY LI_LNTM
ON TABLE HOLD AS TEMPCCAC
END
所以所需的输出实际上是一个 CROSS JOIN (它从每一侧加入一个空白列)。
在 SQL 中:
CREATE TABLE [COSTCENT](
[COST_CTR_NUM] [int] NOT NULL,
[CC_CNM] [varchar](40) NULL,
[CC_DEPT] [varchar](7) NULL,
[CC_ALSRC] [varchar](6) NULL,
[CC_HIER_CODE] [varchar](20) NULL,
CONSTRAINT [PK_LOOKUP_GL_COST_CTR] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY
= OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [JOINGLAC](
[ACCOUNT_NO] [int] NULL,
[LI_LNTM] [int] NULL,
[PR_PRODUCT] [varchar](5) NULL,
[PR_GROUP] [varchar](1) NULL,
[AC_NAME_LONG] [varchar](40) NULL,
[LI_NM_LONG] [varchar](30) NULL,
[LI_INC] [int] NULL,
[LI_MULT] [int] NULL,
[LI_ANLZ] [int] NULL,
[LI_TYPE] [varchar](2) NULL,
[PR_SORT] [varchar](2) NULL,
[PR_NM] [varchar](26) NULL,
[PZ_SORT] [varchar](2) NULL,
[PZNAME] [varchar](26) NULL,
[WANLZ] [varchar](3) NULL,
[OPMLNTM] [int] NULL,
[PS_GROUP] [varchar](5) NULL,
[PS_SORT] [varchar](2) NULL,
[PS_NAME] [varchar](26) NULL,
[PT_GROUP] [varchar](5) NULL,
[PT_SORT] [varchar](2) NULL,
[PT_NAME] [varchar](26) NULL
) ON [PRIMARY]
CREATE TABLE [JOINCCAC](
[CA_JCCAC] [varchar](16) NOT NULL,
[CA_COSTCENT] [int] NOT NULL,
[CA_GLACCOUNT] [int] NOT NULL,
[CA_LNTM] [int] NOT NULL,
[CA_UNIT] [varchar](6) NOT NULL,
CONSTRAINT [PK_JOINCCAC_KNOWN_GOOD] PRIMARY KEY CLUSTERED
(
[CA_JCCAC] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY
= OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
使用 SQL 代码:
INSERT INTO [JOINCCAC]
(
[CA_JCCAC]
,[CA_COSTCENT]
,[CA_GLACCOUNT]
,[CA_LNTM]
,[CA_UNIT]
)
SELECT Util.PADLEFT(CONVERT(varchar, CC.COST_CTR_NUM), '0',
7)
+ Util.PADLEFT(CONVERT(varchar, GL.ACCOUNT_NO), '0',
9) AS CC_JCCAC
,CC.COST_CTR_NUM AS CA_COSTCENT
,GL.ACCOUNT_NO % 900000000 AS CA_GLACCOUNT
,GL.LI_LNTM AS CA_LNTM
,udf_BUPDEF(GL.ACCOUNT_NO, CC.COST_CTR_NUM, GL.LI_LNTM, 'N') AS CA_UNIT
FROM JOINGLAC AS GL
CROSS JOIN COSTCENT AS CC
根据随后如何使用此表,它应该能够从流程中消除,只需加入用于构建它的两个原始表即可。但是,这是一个非常大的移植工作,我可能有一段时间找不到表的用法,所以我想知道是否有任何技巧可以CROSS JOIN
及时 ing 像这样的大表(特别是考虑到现有的流程in FOCUS 能够更快地做到这一点)。这样我就可以验证我构建替换查询的正确性,然后用视图或其他方式将其分解。
我还在考虑将 UDF 和字符串操作分解并首先执行 CROSS JOIN 以稍微分解该过程。
到目前为止的结果:
事实证明,UDF 确实对性能有很大贡献(负面)。但是 15m 行交叉连接和 30m 行交叉连接之间似乎也存在很大差异。我没有 SHOWPLAN 权限(嘘),所以我无法判断它使用的计划在更改索引后是更好还是更差。我还没有重构它,但我希望整个表很快就会消失。