Массивная CROSS JOIN в SQL Server 2005

голоса
2

Я портирование процесса , который создает массивный CROSS JOINиз двух таблиц. Полученная таблица содержит 15 миллионов записей (выглядит как процесс делает крест 30m присоединиться с 2600 строки таблицы и таблицы в 12000 строк , а затем делает некоторую группировку , которая должна разделить его пополам). Строки относительно узкие - всего 6 столбцов. Это работает уже в течение 5 часов без признаков завершения. Я только заметил , что счета расхождение между известным хорошо и то , что я ожидал бы для перекрестного соединения, так что мой вывод не имеет группировки или deduping которая будет вдвое сократить до финального стола , - но это все еще кажется , что он не собирается завершить любого в ближайшее время.

Во-первых, я буду смотреть, чтобы устранить эту таблицу из процесса, если это вообще возможно - очевидно, он может быть заменен путем присоединения к обеим таблицам индивидуально, но сейчас у меня нет видимости в везде используется.

Но учитывая , что существующий процесс делает это (за меньшее время, на менее мощной машине, используя язык FOCUS), есть какие - либо варианты для повышения производительности больших CROSS JOINс в SQL Server (2005) (аппаратное не вариант, это поле представляет собой 64-битный 8-позиционная с 32-ГБ ОЗУ)?

Детали:

Она написана таким образом, в центре внимания (я пытаюсь произвести тот же результат, что является 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 Code:

INSERT IGNORE   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Инги больших таблиц , как , что своевременно (особенно учитывая , что существующий процесс в ФОКУСЕ способен сделать это более быстро). Таким образом , я мог проверить правильность моего здания запроса замены , а позже фактор его с видом или что угодно.

Я также рассматриваю факторизуя пользовательские функции и строку манипуляции и выполнение перекрестного соединения первого разорвать процесс немного.

РЕЗУЛЬТАТЫ ПОКА:

Оказывается, что UDFs вносят свой вклад много (отрицательно) на производительность. Но также, как представляется, большая разница между 15й строкой кросса присоединиться и строчной крестом 30й присоединиться. Я не имею права SHOWPLAN (бу ого-го), поэтому я не могу сказать, является ли план его использования лучше или хуже после изменения индексов. Я не переработан еще, но я ожидал весь стол, чтобы уйти в ближайшее время.

Задан 10/12/2008 в 04:01
источник пользователем
На других языках...                            


3 ответов

голоса
2

Продолжая то, что другие поговорку, функции DB, содержащие запросы, которые используются в отборное всегда мои запросы очень медленно. С верхней части моей головы, я полагаю, я должен был запрос работать в 45 секунд, а затем я убрал функцию, а затем результат был 0 секунд :)

Так проверьте udf_BUPDEF не делает никаких запросов.

Ответил 10/12/2008 в 07:00
источник пользователем

голоса
2

Исследование показывает, что запрос только один столбец, используемый из одной таблицы, и только два столбца, используемого из другой таблицы. В связи с очень низким числом столбцов, используемым, этот запрос может быть легко модернизируются с покрытием индексов:

CREATE INDEX COSTCENTCoverCross ON COSTCENT(COST_CTR_NUM)
CREATE INDEX JOINGLACCoverCross ON JOINGLAC(ACCOUNT_NO, LI_LNTM)

Вот мои вопросы для дальнейшей оптимизации:

Когда вы помещаете запрос в анализаторе запросов и громить кнопку «Ориентировочный план выполнения», он покажет графическое представление того, что он собирается делать.

Регистрация Типа: Там должен быть вложенный цикл там. (Другие варианты слиянием и хэш-соединение). Если вы видите, вложенный цикл, то нормально. Если вы видите слиянием или хеширования, сообщите нам об этом.

Порядок доступа к таблице: пройти весь путь к вершине и прокручивать весь путь направо. Первый шаг должен быть доступ к таблице. Какая таблица является то, что и какой метод используется (сканирование индекса, кластерный индекс сканирования)? Какой метод используется для доступа к другой таблице?

Параллелизм: Вы должны увидеть маленькие jaggedy стрелки почти на всех иконах в плане, указывающей, что параллелизм используется. Если вы не видите этого, существует серьезная проблема!

Это udf_BUPDEF касается меня. Есть ли прочитать его из дополнительных таблиц? Util.PADLEFT касается меня меньше, но все же .. что это? Если это не объект базы данных, а затем рассмотреть вопрос об использовании вместо этого:

RIGHT('z00000000000000000000000000' + columnName, 7)

Существуют ли какие-либо триггеры JOINCCAC? Как насчет индексов? При вставке этой большой, вы хотите, чтобы удалить все триггеры и индексы в этой таблице.

Ответил 10/12/2008 в 06:41
источник пользователем

голоса
1

Разбейте запрос, чтобы сделать простой простой крест присоединиться.


   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

Посмотрите, как хорошо это простой крест присоединиться? (Без каких-либо функций применяются на нем)

Ответил 10/12/2008 в 06:08
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more