请在本文底部找到所有必要的脚本,以创建我在这里描述的场景。
情景:
我有一个“交易”表,我将所有交易存储在股票市场管理应用程序中。所有交易都在那里,并附有相关信息,例如TransactionType,TransactionAmount等
接下来的两个表格非常简单且不言自明,即人与公司。
然后我有一个名为TransactionsForCompanies的表,我存储了公司客户创建的所有交易。在这个表中,我只有两列:TransactionId - 来自Transactions表 - CompanyId - 来自Companies表。
下一个名为TransactionsForPeople的表几乎与最后一个表相同,但它用于识别个人创建的交易。
请参阅数据库结构,我认为这很容易理解。
这就是我想要做的以及我需要帮助的地方。
我想创建一个视图,为人们提供“上次交易日期”。因此,如果一个人在过去一个月内有多个交易,那么这个视图应该是给我那个可能在2个小时之前完成交易的个人的最后交易日期。当然,该视图将返回所有“个人客户”的最后交易日期。
为此,我使用MAX函数,视图效果很好。但是,因为我正在使用MAX函数,所以我无法为视图创建索引。因此,我遇到了性能问题,因为我的“Transactions”表有数百万条记录。
当然,我们的想法是在另一个SELECT语句中使用该视图,这样我就可以生成关于大多数活动客户端和最不活跃客户端的不错报告。这个SELECT语句运行得非常慢,当我查看执行计划时,瓶颈就是我将JOIN连接到使用MAX函数的视图。
问题:如何以能够提供良好性能的方式为交易人员捕获最后一个TransactionDate?
...谢谢
USE [TestDb]
GO
/****** Object: Table [dbo].[Companies] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Companies](
[CompanyId] [int] IDENTITY(1,1) NOT NULL,
[CompanyName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Companies] PRIMARY KEY CLUSTERED
(
[CompanyId] 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
/****** Object: Table [dbo].[People] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[People](
[PersonId] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](20) NOT NULL,
[MiddleName] [nvarchar](20) NULL,
[LastName] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED
(
[PersonId] 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
/****** Object: Table [dbo].[Transactions] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Transactions](
[TransactionId] [int] IDENTITY(1,1) NOT NULL,
[TransactionType] [nvarchar](50) NOT NULL,
[TransactionTimeStamp] [datetime] NOT NULL,
[TransactionAmount] [money] NOT NULL,
[Comments] [nvarchar](50) NULL,
CONSTRAINT [PK_Transactions] PRIMARY KEY CLUSTERED
(
[TransactionId] 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
/****** Object: Table [dbo].[TransactionsForCompanies] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TransactionsForCompanies](
[TransactionId] [int] NOT NULL,
[CompanyId] [int] NOT NULL,
CONSTRAINT [PK_TransactionsForCompanies] PRIMARY KEY CLUSTERED
(
[TransactionId] ASC,
[CompanyId] 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
/****** Object: Table [dbo].[TransactionsForPeople] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TransactionsForPeople](
[TransactionId] [int] NOT NULL,
[PersonId] [int] NOT NULL,
CONSTRAINT [PK_TransactionsForPeople] PRIMARY KEY CLUSTERED
(
[TransactionId] ASC,
[PersonId] 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
SET IDENTITY_INSERT [dbo].[Companies] ON
GO
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (1, N'Company A')
GO
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (2, N'Company B')
GO
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (3, N'Company C')
GO
SET IDENTITY_INSERT [dbo].[Companies] OFF
GO
SET IDENTITY_INSERT [dbo].[People] ON
GO
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (1, N'John', NULL, N'Doe')
GO
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (2, N'Jane', NULL, N'Smith')
GO
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (3, N'Betsy', NULL, N'Green')
GO
SET IDENTITY_INSERT [dbo].[People] OFF
GO
SET IDENTITY_INSERT [dbo].[Transactions] ON
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (1, N'BUY', CAST(0x0000A1990122F5C4 AS DateTime), 300.0000, N'Got it!')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (2, N'BID', CAST(0x0000A19901236069 AS DateTime), 1753.5000, N'My best offer...')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (3, N'SELL', CAST(0x0000A19901236AF5 AS DateTime), 1753.5000, N'Will take it!')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (4, N'BUY', CAST(0x0000A19901236C21 AS DateTime), 1753.5000, N'Finalize purchase.')
GO
SET IDENTITY_INSERT [dbo].[Transactions] OFF
GO
INSERT [dbo].[TransactionsForCompanies] ([TransactionId], [CompanyId]) VALUES (3, 1)
GO
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (1, 2)
GO
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (2, 3)
GO
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (4, 3)
GO
ALTER TABLE [dbo].[Transactions] ADD CONSTRAINT [DF_Transactions_TransactionTimeStamp] DEFAULT (getutcdate()) FOR [TransactionTimeStamp]
GO
ALTER TABLE [dbo].[TransactionsForCompanies] WITH CHECK ADD CONSTRAINT [FK_TransactionsForCompanies_Companies] FOREIGN KEY([CompanyId])
REFERENCES [dbo].[Companies] ([CompanyId])
GO
ALTER TABLE [dbo].[TransactionsForCompanies] CHECK CONSTRAINT [FK_TransactionsForCompanies_Companies]
GO
ALTER TABLE [dbo].[TransactionsForCompanies] WITH CHECK ADD CONSTRAINT [FK_TransactionsForCompanies_Transactions] FOREIGN KEY([TransactionId])
REFERENCES [dbo].[Transactions] ([TransactionId])
GO
ALTER TABLE [dbo].[TransactionsForCompanies] CHECK CONSTRAINT [FK_TransactionsForCompanies_Transactions]
GO
ALTER TABLE [dbo].[TransactionsForPeople] WITH CHECK ADD CONSTRAINT [FK_TransactionsForPeople_People] FOREIGN KEY([PersonId])
REFERENCES [dbo].[People] ([PersonId])
GO
ALTER TABLE [dbo].[TransactionsForPeople] CHECK CONSTRAINT [FK_TransactionsForPeople_People]
GO
ALTER TABLE [dbo].[TransactionsForPeople] WITH CHECK ADD CONSTRAINT [FK_TransactionsForPeople_Transactions] FOREIGN KEY([TransactionId])
REFERENCES [dbo].[Transactions] ([TransactionId])
GO
ALTER TABLE [dbo].[TransactionsForPeople] CHECK CONSTRAINT [FK_TransactionsForPeople_Transactions]
GO
答案 0 :(得分:0)
如果你想使用max()
,你将无法创建索引视图。
如何:
(i)将主键更改为非聚簇,然后在TransactionTimestamp
表的Transactions
上添加聚簇索引?
(ii)在TransactionId, TransactionTimestamp
表上的Transactions
上添加索引。