Наружное соединение на двух столах с последовательными гидами - PullRequest
1 голос
/ 05 марта 2012

Я пытаюсь выполнить полное внешнее соединение двух таблиц, которые не связаны между собой. У каждой таблицы есть location_id, который в конечном итоге сформирует отношение первичного / внешнего ключа (как только я выясню эту проблему производительности). При выполнении внешнего соединения оно просто уходит. Запросы и триггеры, выполненные для каждой таблицы самостоятельно, завершаются менее чем за секунду.

В этой таблице 21000 записей:

CREATE TABLE [dbo].[TBL_LOCATIONS](
    [OBJECTID] [int] NOT NULL,
    [Loc_Name] [nvarchar](100) NULL,
    [Location_ID] [uniqueidentifier] NULL,
    [SHAPE] [geometry] NULL,

 CONSTRAINT [R33_pk] PRIMARY KEY CLUSTERED 
(
    [OBJECTID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 75) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[TBL_LOCATIONS]  WITH CHECK ADD  CONSTRAINT [g17_ck] CHECK  (([SHAPE].[STSrid]=(26917)))
GO
ALTER TABLE [dbo].[TBL_LOCATIONS] ADD  CONSTRAINT [DF_TBL_LOCATIONS_Location_ID]  DEFAULT (newsequentialid()) FOR [Location_ID]
GO

CREATE SPATIAL INDEX [S17_idx] ON [dbo].[TBL_LOCATIONS] 
(
    [SHAPE]
)USING  GEOMETRY_GRID 
WITH (
BOUNDING_BOX =(224827, 3923750, 323464, 3967780), GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

CREATE UNIQUE NONCLUSTERED INDEX [UUID_OID_33] ON [dbo].[TBL_LOCATIONS] 
(
    [Location_ID] ASC,
    [OBJECTID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 75) ON [PRIMARY]
GO

В этой таблице 53000 записей

CREATE TABLE [dbo].[TBL_EVENTS](
    [OBJECTID] [int] NOT NULL,
    [Event_ID] [uniqueidentifier] NULL,
    [Location_ID] [uniqueidentifier] NULL,
 CONSTRAINT [PK_TBL_EVENTS] PRIMARY KEY CLUSTERED 
(
    [OBJECTID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[TBL_EVENTS] ADD  CONSTRAINT [DF_TBL_EVENTS_Event_ID]  DEFAULT (newsequentialid()) FOR [Event_ID]
GO
ALTER TABLE [dbo].[TBL_EVENTS] ADD  CONSTRAINT [DF_TBL_EVENTS_Event_ID]  DEFAULT (newsequentialid()) FOR [Event_ID]
GO

CREATE UNIQUE NONCLUSTERED INDEX [R36_SDE_ROWID_UK] ON [dbo].[TBL_EVENTS] 
(
    [OBJECTID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 75) ON [PRIMARY]
GO

А вот запрос, который выполняется .... и выполняется ... 1 час и результатов нет.

SELECT     
    TBL_LOCATIONS.Loc_Name, 
    TBL_LOCATIONS.Location_ID, 
    TBL_LOCATIONS.SHAPE, 
    TBL_EVENTS.Event_ID
FROM         
    TBL_EVENTS 
FULL OUTER JOIN
    TBL_LOCATIONS ON TBL_EVENTS.Location_ID = TBL_LOCATIONS.Location_ID

Я пробовал каждую перестановку индексов атрибутов в обеих таблицах, перестраивая и реорганизуя их, ничего не влияло на производительность. Использование ObjectID в качестве PK предписано приложением, как и sequentialGUID. Я не думаю, что это факторы здесь, так как обе эти таблицы великолепно работают вне этого запроса. SQL Server 2008 с пакетом обновления 1 (SP1) 64BIT на RAID 10/48 ГБ ОЗУ.

Ответы [ 3 ]

2 голосов
/ 06 марта 2012

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

2 голосов
/ 06 марта 2012

FULL JOIN хорошо работает, когда данные в столбцах, используемые для ссылок на таблицы, уникальны.

Для строк, содержащих дублированные данные FULL JOIN ведет себя как CROSS JOIN и может вызвать проблемы с производительностью.

Так что, вероятно, узкое место возникает из-за дубликатов в столбце LOCATION_ID.

1 голос
/ 06 марта 2012

Если значения связанных полей не настолько уникальны (местоположение), размер запроса может приблизиться к довольно большому числу.

В крайнем примере, если для местоположения в обеих таблицах было указано значение «1», общее количество строк было бы близко к размеру перекрестного соединения, около 1113 000 000 строк (21 000 * 53 000). Запрос такого размера (более миллиарда строк) будет выполняться долго.

РЕДАКТИРОВАТЬ - обновление неверного утверждения, как указано в комментариях

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...