Я портирую процесс, который создает MASSIVE CROSS JOIN
из двух таблиц. Результирующая таблица содержит 15 м записей (похоже, что процесс выполняет 30-миллиметровое перекрестное соединение с таблицей 2600 строк и таблицей 12000 строк, а затем выполняет некоторую группировку, которая должна разбить ее пополам). Ряды относительно узкие - всего 6 столбцов. Он работает в течение 5 часов без каких-либо признаков завершения. Я только что заметил расхождение в подсчете между известным товаром и тем, что я ожидал бы для перекрестного соединения, поэтому в моих выходных данных нет группировки или дедупликации, которые бы делили финальный стол пополам - но все равно кажется, что он не завершит скоро.
Сначала я попытаюсь исключить эту таблицу из процесса, если это вообще возможно - очевидно, ее можно было бы заменить объединением обеих таблиц по отдельности, но сейчас я не вижу нигде, где она используется.
Но, учитывая, что существующий процесс делает это (за меньшее время на менее мощной машине, использующей язык FOCUS), есть ли варианты для повышения производительности больших CROSS JOIN
с в SQL Server (2005) (аппаратное обеспечение) на самом деле это не вариант, это коробка 64-битная 8-полосная с 32-ГБ оперативной памяти)?
подробности:
Это написано так в FOCUS (я пытаюсь произвести тот же вывод, который является CROSS JOIN в SQL):
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
большом использовании таких таблиц (особенно учитывая, что существующий процесс в FOCUS может сделать это быстрее). Таким образом, я мог проверить правильность моего построения запроса на замену, а затем разложить его по представлениям или как угодно.
Я также рассматриваю возможность разделения UDF и манипуляции со строками и выполнения CROSS JOIN в первую очередь, чтобы немного разбить процесс.
РЕЗУЛЬТАТЫ ТАК ДАЛЕЕ:
Оказывается, что UDF вносят большой (отрицательный) вклад в производительность. Но также существует большая разница между 15-метровым перекрестным соединением и 30-метровым перекрестным соединением. У меня нет прав на SHOWPLAN (бу-ху), поэтому я не могу сказать, лучше или хуже план, который он использует, после изменения индексов. Я еще не реорганизовал его, но ожидаю, что весь стол скоро исчезнет.