SQLServer2005中的大规模交叉连接
我正在移植一个进程,该进程创建了两个表的大规模SQLServer2005中的大规模交叉连接,sql,sql-server,sql-server-2005,performance,cross-join,Sql,Sql Server,Sql Server 2005,Performance,Cross Join,我正在移植一个进程,该进程创建了两个表的大规模交叉连接。生成的表包含15m条记录(看起来该进程将2600行表和12000行表进行30m交叉连接,然后进行分组,必须将其拆分为两半)。行相对较窄,只有6列。它已经运行了5个小时,没有完成的迹象。我只是注意到已知货物和交叉连接预期货物之间的计数差异,因此我的输出没有分组或重复数据消除功能,这将使最终表格减半,但这看起来似乎不会很快完成 首先,如果可能的话,我将从流程中删除这个表-显然,可以通过单独连接两个表来替换它,但是现在我无法看到它在其他地方的使用
交叉连接。生成的表包含15m条记录(看起来该进程将2600行表和12000行表进行30m交叉连接,然后进行分组,必须将其拆分为两半)。行相对较窄,只有6列。它已经运行了5个小时,没有完成的迹象。我只是注意到已知货物和交叉连接预期货物之间的计数差异,因此我的输出没有分组或重复数据消除功能,这将使最终表格减半,但这看起来似乎不会很快完成
首先,如果可能的话,我将从流程中删除这个表-显然,可以通过单独连接两个表来替换它,但是现在我无法看到它在其他地方的使用情况
但是,考虑到现有进程可以做到这一点(在时间更短的情况下,在功能较弱的机器上,使用FOCUS语言),在SQL Server(2005)中是否有任何选项可以提高大型交叉连接的性能(硬件不是真正的选项,此框是一个64位8路,具有32 GB的RAM)
详情:
它是以这种方式在焦点中编写的(我试图生成相同的输出,这是SQL中的交叉连接):
因此,所需的输出实际上是一个交叉连接(它从每一侧连接一个空白列)
在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
根据该表随后的使用方式,应该能够通过简单地连接到用于构建该表的两个原始表,将其从流程中删除。然而,这是一个非常大的移植工作,我可能在一段时间内找不到表的用法,因此我想知道是否有什么技巧可以及时地交叉连接这样的大表(特别是考虑到现有的关注进程能够更快地完成)。这样,我就可以验证我构建的替换查询的正确性,然后用视图或其他方式将其分解出来
我还考虑将UDF和字符串操作分解出来,并首先执行交叉连接,以稍微分解这个过程
迄今为止的结果:
事实证明,UDF确实对性能做出了很大(负面)贡献。但15m行交叉连接和30m行交叉连接之间似乎也有很大区别。我没有SHOWPLAN权限(boo-hoo),因此我无法判断它正在使用的计划在更改索引后是更好还是更差。我还没有对它进行重构,但我希望整个表很快就会消失。将查询分解为简单的交叉连接
SELECT CC.COST_CTR_NUM, GL.ACCOUNT_NO
,CC.COST_CTR_NUM AS CA_COSTCENT
,GL.ACCOUNT_NO AS CA_GLACCOUNT
,GL.LI_LNTM AS CA_LNTM
-- I don't know what is BUPDEF doing? but remove it from the query for time being
-- ,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
看看简单交叉连接有多好?(没有应用任何函数)检查该查询只显示一个表中使用的一列,另一个表中使用的两列。由于使用的列数非常少,因此可以使用覆盖索引轻松增强此查询:
CREATE INDEX COSTCENTCoverCross ON COSTCENT(COST_CTR_NUM)
CREATE INDEX JOINGLACCoverCross ON JOINGLAC(ACCOUNT_NO, LI_LNTM)
以下是我需要进一步优化的问题:
当您将查询放入查询分析器并点击“ShowEstimated execution plan”(显示估计的执行计划)按钮时,它将显示它将要执行的操作的图形表示
连接类型:其中应该有嵌套的循环连接。(其他选项为合并联接和哈希联接)。如果看到嵌套循环,则单击“确定”。如果您看到合并联接或哈希联接,请告诉我们
表格访问顺序:一直到顶部并向右滚动。第一步应该是访问表。这是哪一个表,使用了什么方法(索引扫描、聚集索引扫描)?使用什么方法访问另一个表
并行性:您应该在计划中的几乎所有图标上看到小锯齿状箭头,指示正在使用并行性。如果你看不到这一点,那就是一个大问题
这个udf_BUPDEF与我有关。它是否从其他表格中读取?Util.PADLEFT与我关系不大,但仍然。。它是什么?如果它不是数据库对象,则考虑使用此替代:
RIGHT('z00000000000000000000000000' + columnName, 7)
Joincac上有触发器吗?索引呢?插入这么大,您将希望删除该表上的所有触发器和索引。继续其他人所说的,包含select中使用的查询的DB函数总是使我的查询速度非常慢。毫无疑问,我相信我在45秒内运行了一个查询,然后我删除了该函数,结果是0秒:)
因此,检查udf_BUPDEF没有执行任何查询 如果效果很快,试着只执行SELECT(应用函数),看看是否仍然可以?UDF性能(它们是标量的,不访问表)是关键,非常糟糕-这两个UDF每秒只能处理大约300行。我目前正在寻找解决办法。“大规模交叉连接”,即应该在SQL语言中引入语法:BUPDEF是一个巨大的业务逻辑函数,它是被移植的。希望它会消失(如此表),但其中没有查找(或我为清楚起见遗漏的另一个UDF)。UDF性能是关键,非常糟糕-这两个UDF每秒只能处理大约300行。我目前正在寻找解决办法。UDF的性能(它们是标量的,不访问表)是关键,而且非常糟糕——这两个UDF每秒只能处理大约300行。我目前正在寻找解决办法。
RIGHT('z00000000000000000000000000' + columnName, 7)