我们有一个非常古老的vb.net winforms应用程序,它使用sql server作为其数据库。我们的应用是这样的,我们必须在我们的系统中存储各种模块的变化,例如。 CustomerAccident,CustomerAdmission等,还插入一个简短的描述和许多其他guid来建立我们的dailyReporting表中发生的不同类型事件之间的关系(即数据以非常规范的方式存储)。当我们显示此报告表中的数据时,我们创建了一个视图,以帮助我们提供数据的非规范化形式,然后我们将这些数据显示在客户记录中。
正如您可以想象的那样,对于我们的客户来说,这个报告表现在有超过一百万行。现在,每次客户端尝试查看客户记录时,因为查询必须经过这么多行,所以需要花费大量时间来运行查询,并且在某些情况下会阻塞几个表,这会导致其他用户出现问题。
为了解决这个问题,我们考虑创建一个全新的报告数据库,并以非规范化的形式存储信息,并使用触发器在视图中填充各种表格。
我知道这可能是一个有点模糊的问题,但我正在寻找其他想法,如果有其他人有这种情况的经验。
以下是用于获取信息的SQL查询
exec sp_executesql N'
SELECT
''Customer Report'' AS type
, CASE --Record Type
WHEN cv_customerDailyReport.type & 12 = 12
OR cv_customerDailyReport.type & 19 = 19
OR cv_customerDailyReport.type & 65 = 65 THEN
''ABC''
WHEN cv_customerDailyReport.type & 54 = 54 THEN
''CDE''
WHEN cv_customerDailyReport.type & 96 = 96 THEN
''REW''
ELSE
cv_customerDailyReport.Description
END AS ReportType
, CASE -- SUB TYPE
WHEN cv_customerDailyReport.type & 258 = 258 THEN
''QWE''
WHEN cv_customerDailyReport.type & 321 = 321 THEN
''RTY''
WHEN cv_customerDailyReport.type & 1 = 1 THEN
''AGX''
WHEN cv_customerDailyReport.type & 8 = 8 THEN
''CTE''
WHEN cv_customerDailyReport.type & 16 = 16 THEN
''TYU''
ELSE
''other''
END AS subtype
, cv_customerDailyReport.customerDailyRecord AS ''guid''
, cv_customerDailyReport.ActionDate
, COALESCE(userTable.name,''exStaff'') as ''By''
, CASE
WHEN cv_customerDailyReport.Improvement=0 THEN
(''Unsure / NA'')
WHEN cv_customerDailyReport.Improvement=1 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input2'') THEN
(SELECT value FROM optionsTable WHERE name=''Input2'')
ELSE ''Improved''
END
)
WHEN cv_customerDailyReport.Improvement=258 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input3'') THEN
(SELECT value FROM optionsTable WHERE name=''Input3'')
ELSE
''Not change''
END
)
WHEN cv_customerDailyReport.Improvement=3 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input4'') THEN
(SELECT value FROM optionsTable WHERE name=''Input4'')
ELSE
''Bad''
END
)
END AS ''Improvement''
, CASE
WHEN cv_customerDailyReport.type & 258 = 258 THEN
convert(varchar,cv_customerDailyReport.measurementValue) + '' '' + chemist.Name -- + '', '' + cv_customerDailyReport.observationText
+ '' '' +
(
CASE
WHEN (cv_customerDailyReport.comment<>'''' or cv_customerDailyReport.comment<>null) THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Feedbackquestion'') THEN
(SELECT value FROM optionsTable WHERE name=''Feedbackquestion'')
ELSE
''Please comment''
END
)
+ '' - ''+
(
CASE
WHEN cv_customerDailyReport.Improvement=0 THEN
(''Unsure / NA'')
WHEN cv_customerDailyReport.Improvement=1 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input2'') THEN
(SELECT value FROM optionsTable WHERE name=''Input2'')
ELSE
''Improved''
END
)
WHEN cv_customerDailyReport.Improvement=258 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input3'') THEN
(SELECT value FROM optionsTable WHERE name=''Input3'')
ELSE
''Unchanged''
END
)
WHEN cv_customerDailyReport.Improvement=3 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input4'') THEN
(SELECT value FROM optionsTable WHERE name=''Input4'')
ELSE
''Deteriorated''
END
)
END
)
+ '' - '' + cv_customerDailyReport.comment
ELSE
''''
END
)
WHEN cv_customerDailyReport.type & 321 = 321
AND cv_customerDailyReport.measurementValue <> 0 THEN
-- measurment
CASE
WHEN (MeasurementType.StatusFlags & 16 = 16 ) THEN
cv_customerDailyReport.measurementValueAndType
+ '' - '' + convert(varchar,COALESCE(CONVERT(INT,cv_customerDailyReport.measurementValue),0))
+ ''/'' + convert(varchar,COALESCE(CONVERT(INT,cv_customerDailyReport.measurementValue2),0))
ELSE
cv_customerDailyReport.measurementValueAndType
+ '' - '' + convert(varchar,COALESCE(cv_customerDailyReport.measurementValue,0))
END
+ '' '' +
(
CASE
WHEN(cv_customerDailyReport.comment <> ''''
or cv_customerDailyReport.comment<>null) THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Feedbackquestion'') THEN
(SELECT value FROM optionsTable WHERE name=''Feedbackquestion'')
ELSE
''Do you think the person’s quality of life has improved?''
END
)
+ '' - '' +
(
CASE
WHEN cv_customerDailyReport.Improvement=0 THEN
(''Unsure / NA'')
WHEN cv_customerDailyReport.Improvement=1 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input2'') THEN
(SELECT value FROM optionsTable WHERE name=''Input2'')
ELSE
''Improved''
END
)
WHEN cv_customerDailyReport.Improvement=258 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input3'') THEN
(SELECT value FROM optionsTable WHERE name=''Input3'')
ELSE
''Unchanged''
END
)
WHEN cv_customerDailyReport.Improvement=3 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input4'') THEN
(SELECT value FROM optionsTable WHERE name=''Input4'')
ELSE
''Deteriorated''
END
)
END
)
+ '' - '' + cv_customerDailyReport.comment
ELSE
''''
END
)
WHEN cv_customerDailyReport.type & 485 = 485 THEN
(
SELECT top 1
CASE
WHEN pain = 1 THEN
''DER = True'' + '' - ''
ELSE
''''
END
+
CASE
WHEN woundGrade = 1 THEN
''Grade : '' + ''Ungraded'' + '' - ''
WHEN woundGrade = 258 THEN
''Grade : '' +''Grade 1'' + '' - ''
WHEN woundGrade = 3 THEN
''Grade : '' +''Grade 258'' + '' - ''
WHEN woundGrade = 321 THEN
''Grade : '' +''Grade 3'' + '' - ''
WHEN woundGrade = 5 THEN
''Grade : '' +''Grade 321'' + '' - ''
ELSE
''''
END
+
CASE
WHEN NullIF(Location , '''') IS NOT NULL THEN
''Location : '' + Location + '' - ''
ELSE
''''
END
+
'' Width : '' + ISNULL(convert(VARCHAR ,woundWidth),''N/A'') + '' - '' +
'' Lenth : '' + ISNULL(convert(VARCHAR ,woundLength), ''N/A'')
FROM
customerWoundHistory
WHERE
customerWoundHistoryId = cv_customerDailyReport.customerDailyRecord
)
ELSE
cv_customerDailyReport.observationText
+ '' '' +
(
CASE
WHEN (cv_customerDailyReport.comment <> ''''
or cv_customerDailyReport.comment<>null) THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Feedbackquestion'') THEN
(SELECT value FROM optionsTable WHERE name=''Feedbackquestion'')
ELSE
''Do you think quality has improved?''
END
)
+ '' - ''+
(
CASE
WHEN cv_customerDailyReport.Improvement=0 THEN
(''Unsure / NA'')
WHEN cv_customerDailyReport.Improvement=5 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input2'') THEN
(SELECT value FROM optionsTable WHERE name=''Input2'')
ELSE
''Improved''
END
)
WHEN cv_customerDailyReport.Improvement=258 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input3'') THEN
(SELECT value FROM optionsTable WHERE name=''Input3'')
ELSE
''Unchanged''
END
)
WHEN cv_customerDailyReport.Improvement=31 THEN
(
SELECT
CASE
WHEN EXISTS(SELECT value FROM optionsTable WHERE name=''Input4'') THEN
(SELECT value FROM optionsTable WHERE name=''Input4'')
ELSE
''Deteriorated''
END
)
END
)
+ '' - '' + cv_customerDailyReport.comment
ELSE
''''
END
)
END AS ''action''
, cv_customerDailyReport.comments AS ''text''
, cv_customerDailyReport.timestamp
, cv_customerDailyReport.Status
, CASE
WHEN(attachmentTable.category=''QWE'') THEN
1
ELSE
0
END AS ''hasattachment''
, CASE
WHEN(cv_customerDailyReport.type & @sign = @sign) THEN
1
ELSE
0
END AS ''hasBeenLookedAt''
, CASE
WHEN(cv_customerDailyReport.type & 65536 = 65536) THEN
1
ELSE
0
END AS ''IsAvailable''
, cv_customerDailyReport.sourceSystem
, cv_customerDailyReport.ADLIDs
, CASE
WHEN DATEDIFF(MINUTE, actionDate, completedDate) < 0 THEN
0
ELSE
DATEDIFF(MINUTE, actionDate, completedDate)
END AS Duration
FROM
cv_customerDailyReport
LEFT OUTER JOIN userTable on cv_customerDailyReport.createdbyuser = userTable.guid
LEFT OUTER JOIN chemist on cv_customerDailyReport.medicine = chemist.medication
LEFT OUTER JOIN enumnerationTable as MeasurementType ON cv_customerDailyReport.measurementType = MeasurementType.guid
LEFT JOIN attachmentTable on attachmentTable.parentID=cv_customerDailyReport.customerDailyRecord and attachmentTable.category=''DailyAttachmentFile''
WHERE
ActionDate <= getDate()
AND cv_customerDailyReport.status IN (@completed, @completedAndPaid, @Void, @Cancelled, @authorised)
AND cv_customerDailyReport.customer = @customer
AND (
cv_customerDailyReport.ActionDate >= @FromDate
OR cv_customerDailyReport.timestamp > @FromTimeStamp
)
AND (
cv_customerDailyReport.categoryDescription LIKE @filterText
OR cv_customerDailyReport.observationText LIKE @filterText
OR cv_customerDailyReport.comments LIKE @filterText
OR chemist.Name LIKE @filterText
)
AND (
(
@maxAge = 0 AND cv_customerDailyReport.ActionDate >= @FromDate
)
OR (
cv_customerDailyReport.ActionDate >= DATEADD(day, -@maxAge, @CurrentDate)
)
)
UNION
SELECT
''event'' AS type
, CASE customerHistory.type
WHEN 0 THEN
''UIO''
WHEN 258 THEN
''DER''
WHEN 3 THEN
''WER''
WHEN 1 THEN
''SDE''
ELSE
''Diary''
END AS subtype
, ''event'' AS categoryType
, customerHistory.guid AS ''guid''
, customerHistory.dateStarted AS ActionDate
, ISNULL ((SELECT name FROM userTable WHERE individualCustomerHostory.lastupdatedbyuser = userTable.guid),''system'') AS ''By''
, '''' AS ''Improvement''
, customerHistory.comments AS ''action''
, individualCustomerHostory.completedNotes AS ''text''
, individualCustomerHostory.timestamp
, individualCustomerHostory.status
, CASE
WHEN(attachmentTable.category = ''DailyAttachmentFile'') THEN
1
ELSE
0
END AS ''hasattachment''
, '''' As ''hasBeenLookedAt''
, '''' AS ''IsAvailable''
, ''0'' AS sourceSystem
, '''' AS Categoryids
, '''' AS Duration
FROM
customerHistory
LEFT OUTER JOIN roomInfo on customerHistory.room = roomInfo.unit
LEFT JOIN attachmentTable on attachmentTable.parentID=customerHistory.guid AND attachmentTable.category = ''DailyAttachmentFile''
WHERE
customerHistory.customer = @customer
AND (
customerHistory.lastUpdated >= @FromDate
OR individualCustomerHostory.timestamp > @FromTimeStamp
)
AND (
(
roomInfo.shortName LIKE @filterText
OR roomInfo.fullName LIKE @filterText
)
OR customerHistory.type > 0
)
AND (
(
@maxAge = 0 AND customerHistory.dateStarted >= @FromDate
)
OR (
customerHistory.dateStarted >= DATEADD(day, -@maxAge, @CurrentDate)
)
)
UNION
SELECT
''Calendar appointment'' AS ''type''
, ''Calendar appointment'' AS ''categoryType''
, ''Calendar appointment'' AS ''subtype''
, customerAppointmentsAttendees.appointment AS ''guid''
, customerAppointments.StartTime AS ''ActionDate''
, ISNULL((SELECT name FROM userTable WHERE customerAppointments.lastupdatedbyuser = userTable.guid),''system'') AS ''By''
, '''' AS ''Improvement''
, customerAppointments.Description AS ''action''
, customerAppointments.completedNotes AS ''text''
, customerAppointments.timestamp
, 0
, 0 as ''hasattachment''
, '''' As ''hasBeenLookedAt''
, '''' AS ''IsAvailable''
, ''0'' AS sourceSystem
, '''' AS Categoryids
, '''' AS Duration
FROM
customerAppointments
JOIN customerAppointmentsAttendees on customerAppointmentsAttendees.appointment = customerAppointments.appointment
WHERE
customerAppointments.completed = 1
AND customerAppointmentsAttendees.Attendee = @customer
AND (
(
@maxAge = 0 AND customerAppointments.StartTime >= @FromDate
)
OR (
customerAppointments.StartTime >= DATEADD(day, -@maxAge, @CurrentDate)
)
)
UNION
SELECT
''Accident'' AS type
, ''Accident'' AS subtype
, ''Accident'' AS categoryType
, customerAccident.accident AS ''guid''
, customerAccident.accidentDate AS ActionDate
, ISNULL((SELECT name FROM userTable WHERE customerAccident.lastupdatedbyuser = userTable.guid),''system'') AS ''By''
, '''' as ''Improvement''
, customerAccident.accidentRef
+ '' - '' +
CASE
WHEN customerAccident.personalInjury = 1 THEN
''Injury''
WHEN customerAccident.nearMiss = 1 THEN
''Near miss''
WHEN customerAccident.propertyDamage = 1 THEN
''Property damage''
WHEN customerAccident.risk = 1 THEN
''Risk''
ELSE
''Other''
END AS ''action''
, CAST(customerAccident.injuryNature AS VARCHAR(4096)) AS ''text''
, customerAccident.timestamp
, 0
, 0 as ''hasattachment''
, '''' As ''hasBeenLookedAt''
, '''' AS ''IsAvailable''
, ''0'' AS sourceSystem
, '''' AS Categoryids
, '''' AS Duration
FROM
customerAccident
WHERE
customerAccident.customer = @customer
AND (
(
@maxAge = 0 AND customerAccident.accidentDate >= @FromDate
)
OR (
customerAccident.accidentDate >= DATEADD(day, -@maxAge, @CurrentDate)
)
)
UNION
SELECT
''Incident'' AS type
, ''Incident'' AS subtype
, ''Incident'' AS categoryType
, customerIncident.incident AS ''guid''
, customerIncident.incidentDate AS ActionDate
, ISNULL((SELECT name FROM userTable WHERE customerIncident.lastupdatedbyuser = userTable.guid),''system'') AS ''By''
, '''' AS ''Improvement''
, customerIncident.incidentRef + '' - '' + customerIncident.intensity AS ''action''
, CAST(customerIncident.narrative AS VARCHAR(4096)) AS ''text''
, customerIncident.timestamp
, 0
, 0 AS ''hasattachment''
, '''' As ''hasBeenLookedAt''
, '''' AS ''IsAvailable''
, ''0'' AS sourceSystem
, '''' AS Categoryids
, '''' AS Duration
FROM
customerIncident
WHERE
customerIncident.person = @customer
AND (
(
@maxAge = 0 AND customerIncident.incidentDate >= @FromDate
)
OR (
customerIncident.incidentDate >= DATEADD(day, -@maxAge, @CurrentDate)
)
)
ORDER BY
ActionDate Desc
',N'@customer uniqueidentifier,@FromDate datetime,@FromTimeStamp varbinary(8),@filterText nvarchar(258),@completed int,@completedAndPaid int,@Void int,@Cancelled int,@report nvarchar(9),@CurrentDate datetime,@sign int,@authorised int,@maxAge int',@customer='C661135D-0331-4544-82A7-335C2E7D40AF',@FromDate='2014-10-30 00:00:00',@FromTimeStamp=0x0000000000000000,@filterText=N'%%',@completed=15,@completedAndPaid=18,@Void=17,@Cancelled=20,@report=N'Customer Support',@CurrentDate='2014-11-06 00:00:00',@sign=524,@authorised=21,@maxAge=0
视图是cv_customerDailyReport,并且表customerHistory已被编入索引。我们已经运行了执行计划并尝试根据它们添加更多索引,但我们仍然遇到了缓慢的问题。
非常感谢任何帮助。