我有两个名为Visit和VisitMovement的表,它们是1对多关系,即1个访问可以有许多VisitMovement行。我已经取出了所有细节字段,但这些是表格定义:
CREATE TABLE [dbo].[Visit]
(
[VisitID] [int] IDENTITY(1,1) NOT NULL
)
CREATE TABLE [dbo].[VisitMovement](
[VisitMovementID] [int] IDENTITY(1,1) NOT NULL,
[VisitID] [int] NOT NULL
)
很多时候我需要返回访问以及最新的VisitMovement行中的详细信息。
目前我所做的就是拥有这两个视图,但随着时间的推移它会变慢。
例如,如果我从vwGetVisit中选择*,其中VisitID = 1245,则需要几秒钟才能返回,并且vwLatestVisitMovement对象的成本大部分都在结束。
实现这一目标的更好方法是什么?
CREATE VIEW [dbo].[vwGetVisit] as
SELECT
V.*
VM.*
FROM
Visit V
INNER JOIN VisitMovement VM ON
V.VisitID = VM.VisitID
INNER JOIN vwLatestVisitMovement LVM on
VM.VisitMovementID = LVM.VisitMovementID
....many other joins including left joins....
CREATE View [dbo].[vwLatestVisitMovement]
AS
SELECT
VisitID,
max(VisitMovementID) as VisitMovementID
FROM
dbo.VisitMovement
GROUP BY
VisitID
答案 0 :(得分:1)
您在VisitMovementID上使用vwLatestVisitMovement加入visitMovement。这对我来说很奇怪... vwLatestVisitMovement .VisitMovementId是使用MAX计算的,并且需要花费大量的时间来加入这个字段。我认为可以更自然地通过VisitID上的访问加入vwLatestVisitMovement,你应该得到相同的结果,但更好的查询计划。
如果您需要来自VisitMOvement的alla数据,您可以使用CROSS APPLY或ROW_NUMBER()OVER。
通常我更喜欢ROW_NUMBER()OVER。
试试这个,看看性能是否更好:
CREATE VIEW [dbo].[vwGetVisit] as
SELECT
V.*
, LVM.*
FROM
Visit V
INNER JOIN vwLatestVisitMovement LVM on
V.VisitID = LVM.VisitID
....many other joins including left joins....
CREATE View [dbo].[vwLatestVisitMovement]
AS
WITH LVM AS (
-- replace * with fields!
SELECT VM.*
, ROW_NUMBER() OVER(PARTITION BY VM.VisitID ORDER BY VM.VisitMovementID DESC) AS CheckLastId
FROM dbo.VisitMovement AS VM
)
SELECT
*
FROM
LVM
WHERE CheckLastId = 1
GO
交叉appply:
CREATE VIEW [dbo].[vwGetVisit] as
SELECT
V.*
, LVM.*
FROM
Visit V
CROSS APPLY (SELECT TOP (1) LM.* FROM dbo.VisitMovement AS LM WHERE LM.VisitID = V.VisitID ORDER BY LM.VisitMovementID DESC ) AS LVM
....many other joins including left joins....
答案 1 :(得分:0)
three.min.js:326 - Uncaught TypeError: Cannot read property 'x' of undefined
上的索引应该有助于解决您的问题:
VisitID
视图效果不佳但是,如果继续遇到性能问题,最好还是根据需要重复查询。