Я пытаюсь выполнить полное внешнее соединение двух не связанных таблиц. У каждой таблицы есть 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 разрешено приложением, как и последовательный идентификатор GUID. Я не думаю, что это факторы здесь, поскольку обе эти таблицы прекрасно работают вне этого запроса. SQL Server 2008 SP1 64BIT на RAID 10/48 ГБ RAM.
3 ответа
FULL JOIN
хорошо работает, когда данные в столбцах, используемых для связывания таблиц, уникальны.
Для строк, содержащих повторяющиеся данные, FULL JOIN
ведет себя как CROSS JOIN
и может вызвать проблемы с производительностью.
Так что, вероятно, узкое место происходит из-за дубликатов в столбце LOCATION_ID
.
Возможно, вам стоит подумать об отключении журнала транзакций, пока вы все это делаете.
Если значения связанных полей не так уж уникальны (местоположение), размер запроса может приблизиться к довольно большому числу.
В крайнем примере, если бы для местоположения в обеих таблицах было только значение «1», общее количество строк было бы близко к размеру перекрестного соединения, примерно 1113000000 строк (21000 * 53000). Запрос такого размера (более миллиарда строк) займет много времени.
РЕДАКТИРОВАТЬ - обновление неправильного оператора, как указано в комментариях
Похожие вопросы
Новые вопросы
sql-server
Microsoft SQL Server - это система управления реляционными базами данных (RDBMS). Используйте этот тег для всех выпусков SQL Server, включая Compact, Express, Azure, Fast-track, APS (ранее PDW) и Azure SQL DW. Не используйте этот тег для других типов СУБД (MySQL, PostgreSQL, Oracle и т. Д.). Не используйте этот тег для проблем, связанных с разработкой программного обеспечения и мобильных устройств, если только он не связан напрямую с базой данных.