У меня есть большая таблица (между 74 и 88 миллионами строк), которая является средней таблицей (Таблица B) отношения многих ко многим. У меня есть представление, которое строит единую картину данных, содержащихся в этих таблицах. Представление имеет кластеризованный индекс, определенный для него.
Таблица A в левой части моей большой таблицы является основной таблицей в моей базе данных. Таблица C - это таблица, содержащая нормализованные элементы данных. Когда я вставляю новую запись в таблицу C, задача занимает много времени (5 минут на очень хорошем сервере). Это потому, что SQL-сервер перестраивает часть кластеризованного индекса в представлении (я вижу вставку кластерного индекса в фактический план выполнения). Это несмотря на то, что новая строка в таблице C не упоминается в таблице B. Вставка строк в таблицу A и таблицу B занимает миллисекунды, как я и ожидал. База данных не разбита на разделы.
Это раздраженная версия скрипта создания таблиц. Я оставил в столбцах, которые не используются, чтобы вы могли увидеть полную структуру таблиц.
CREATE TABLE [dbo].[TableA] (
[TableAId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED ,
[TableAIdGUID] [uniqueidentifier] NOT NULL,
[ImportantId] [INT] NOT NULL ,
[DateCreated] [datetime] NOT NULL ,
[OtherId2] [int] NOT NULL ,
[TableATypeId] [int] NOT NULL ,
[Active] [bit] NOT NULL ,
[AuditUser] [NVARCHAR] (20) NULL ,
[AuditTime] [datetime] NULL
)
GO
CREATE TABLE [dbo].[TableB] (
[TableBId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED ,
[TableBGUID] [uniqueidentifier] NOT NULL,
[TableAId] [INT] NOT NULL ,
[TableCId] [INT] NOT NULL ,
[Tag] [NVARCHAR] (50) NULL ,
[Order] [tinyint] NOT NULL ,
[DateCreated] [datetime] NOT NULL ,
[Date1] [datetime] NULL ,
[Date2] [datetime] NULL ,
[LastUpdated] [datetime] NOT NULL ,
[Active] [bit] NOT NULL ,
[AuditUser] [NVARCHAR] (20) NULL ,
[AuditTime] [datetime] NULL
)
GO
CREATE TABLE [dbo].[TableC] (
[TableCId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED ,
[TableCIdGUID] [uniqueidentifier] NOT NULL,
[TableCTypeId] [int] NOT NULL ,
[TableCValue] [NVARCHAR] (255) NOT NULL ,
[Frequency] [float] NOT NULL DEFAULT 1,
[TableCValue2] [NVARCHAR] (255) NULL ,
[AuditUser] [NVARCHAR] (20) NULL ,
[AuditTime] [datetime] NULL
)
GO
CREATE VIEW [dbo].[vwTables]
WITH SCHEMABINDING ,ENCRYPTION
AS
SELECT dbo.[TableB].TableBId,
dbo.[TableB].TableAId,
dbo.TableA.ImportantId,
dbo.TableC.TableCValue,
dbo.TableC.TableCValue2,
dbo.TableC.TableCTypeId,
dbo.TableA.TableATypeId
FROM dbo.[TableB] INNER JOIN
dbo.TableC ON dbo.[TableB].TableCId = dbo.TableC.TableCId INNER JOIN
dbo.TableA ON dbo.[TableB].TableAId = dbo.TableA.TableAId
WHERE (dbo.[TableB].Active = CAST(1 AS BIT)) AND (dbo.TableC.TableCValue<>'') and (dbo.TableC.TableCValue is not null)
GO
CREATE UNIQUE CLUSTERED INDEX [IX_vwTables] ON [dbo].[vwTables]
(
[TableCValue] ASC,
[TableCTypeId] ASC,
[TableBId] ASC,
[ImportantId] ASC
)
GO
ALTER TABLE [dbo].[TableB] ADD
CONSTRAINT [FK_TableB_TableC] FOREIGN KEY
(
[TableCId]
) REFERENCES [dbo].[TableC] (
[TableCId]
),
CONSTRAINT [FK_TableB_TableA] FOREIGN KEY
(
[TableAId]
) REFERENCES [dbo].[TableA] (
[TableAId]
)
GO
CREATE NONCLUSTERED INDEX [IX_TableA_Nonclustered] ON [dbo].[TableA]
(
[ImportantId] ASC,
[TableAId] ASC,
[TableATypeId] ASC,
[Active] ASC
)
GO
CREATE NONCLUSTERED INDEX [IX_TableA_OtherId2] ON [dbo].[TableA]
(
[AuditTime] ASC,
[OtherId2] ASC
)
GO
CREATE NONCLUSTERED INDEX [IX_TableB_NonClustered] ON [dbo].[TableB]
(
[TableAId] ASC,
[TableBId] ASC,
[Active] ASC
)
GO
CREATE NONCLUSTERED INDEX [IX_EntityAttributes_NonClustered_2] ON [dbo].[TableB]
(
[TableBId] ASC,
[TableAId] ASC,
[TableCId] ASC,
[Tag] ASC,
[Active] ASC
)
GO
Ниже приведен пример запроса:
SELECT Query.ImportantId
FROM(
SELECT b.ImportantId
FROM [vwTables] a WITH (NOLOCK)
INNER JOIN [vwTables] b WITH (NOLOCK, NOEXPAND) ON a.TableCValue = b.TableCValue
WHERE a.ImportantId = @ImportantId AND
a.TableATypeId=3 AND b.TableATypeId=3
) As Query
GROUP BY Query.ImportantId
Кто-нибудь знает, как я могу заставить вставки в таблицу C происходить (почти) мгновенно, как вставки в TableA и TableB?