У меня есть запрос с 4 запросами на выбор, объединенными Union All, чтобы вернуть один набор результатов, это довольно сложные запросы на выбор, но объединения не задействованы, они фактически выбирают из двух разных представлений. Я просто пытаюсь его оптимизировать, но не совсем уверен, с чего начать. В «фактическом плане выполнения» говорится, что «оценочная стоимость поддерева» составляет 2,12357, я всегда предполагал, что если она превышает 1, то это довольно медленный запрос? это верное предположение? Я также проверил весь план, и там нет сканирования таблиц, только сканирование кластеризованного индекса и поиск кластеризованного индекса, которые, как я снова предполагаю, в порядке? Однако существует множество хэш-совпадений. В любом случае этот запрос будет выполняться много раз, поэтому я бы хотел, чтобы он был оптимизирован как можно лучше. Надеюсь, это имеет какой-то смысл.
Хорошо, SQL выглядит так
CREATE PROCEDURE [dbo].[CompareFiles] -- Add the parameters for the stored procedure here
@VersionID int,
@SyncRequestID int,
@RegionID int,
@LanguageID int
AS
BEGIN
SELECT 'Delete' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer, FileSize FROM View1
WHERE NOT EXISTS(SELECT 1 FROM View2 where View2.FullPath = View1.FullPath
AND View2.VersionId = @VersionID
AND View2.RegionID = @RegionID
AND View2.LanguageID = @LanguageID
)
AND View1.SyncRequestID = @SyncRequestID
UNION ALL
SELECT 'Add' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer,FileSize FROM View2
WHERE NOT EXISTS(SELECT 1 FROM View1 where View1.FullPath = View2.FullPath AND View1.SyncRequestID = @SyncRequestID)
AND
View2.VersionId = @VersionID
AND View2.RegionID = @RegionID
AND View2.LanguageID = @LanguageID
UNION ALL
SELECT 'Delete' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer, FileSize FROM View2
WHERE EXISTS
(
SELECT 1 FROM View2 fd2
WHERE
View2.FullPath = fd2.FullPath AND fd2.VersionID = @VersionID
AND
View2.FileNameOnServer <> fd2.FileNameOnServer
AND
fd2.RegionID = @RegionID
AND
fd2.LanguageID = @LanguageID
)
AND
View2.VersionId = (SELECT VersionID FROM SyncRequest WHERE SyncRequestID = @SyncRequestID)
AND
View2.RegionID = @RegionID
AND
View2.LanguageID = @LanguageID
UNION ALL
SELECT 'Add' AS Action, Type, SUBSTRING(FullPath,2,LEN(FullPath)-1) AS FullPath, FileNameOnServer, FileSize FROM View2
WHERE EXISTS
(
SELECT 1 FROM View2 fd2
WHERE
View2.FullPath = fd2.FullPath AND fd2.VersionID = (SELECT VersionID FROM SyncRequest WHERE SyncRequestID = @SyncRequestID)
AND
View2.FileNameOnServer <> fd2.FileNameOnServer
AND
fd2.RegionID = @RegionID
AND
fd2.LanguageID = @LanguageID
)
AND
View2.VersionId = @VersionID
AND
View2.RegionID = @RegionID
AND
View2.LanguageID = @LanguageID
END
Посмотреть 1 определение
SELECT DISTINCT fqp.Path + '/' + ISNULL(f.Name, '') + ISNULL(f.Extension, '') AS FullPath, fl.LanguageID, fr.RegionID, f.FileID, dbo.CIT_APD_Versions.ApID, f.FileNameOnServer, dbo.Versions.VersionID, (CASE WHEN FileNameOnServer IS NULL THEN 'Folder' ELSE 'File' END) AS Type, f.FileSize
FROM dbo.FileRegions AS fr
RIGHT OUTER JOIN dbo.Files AS f
INNER JOIN dbo.FilePaths AS fp ON fp.FileID = f.FileID ON fr.FileID = f.FileID
LEFT OUTER JOIN dbo.FileLanguages AS fl ON fl.FileID = f.FileID
LEFT OUTER JOIN dbo.RoleFiles AS fro ON fro.FileID = f.FileID
RIGHT OUTER JOIN dbo.Versions
INNER JOIN dbo.View3 AS fqp ON dbo.VersionID = fqp.VersionID ON fqp.PathID = fp.PathID
Вид 2 Определение
SELECT '//' + dbo.CIT_APD_SyncRequestFiles.FullPath AS FullPath, NULL AS LanguageID, NULL AS RegionID, NULL AS FileID, NULL AS ApID,
dbo.SyncRequest.VersionID, '' AS FileNameOnServer, '' AS Type, NULL AS FileSize, dbo.SyncRequestFiles.SyncRequestID
FROM dbo.SyncRequestFiles
INNER JOIN dbo.CIT_APD_SyncRequest ON dbo.SyncRequestFiles.SyncRequestID = dbo.SyncRequest.SyncRequestID
Вид 3 Определение
WITH Parent AS (SELECT PathID, ParentPathID, VersionID, CONVERT(varchar(128), Path) AS Path
FROM dbo.Paths AS ParentPaths
WHERE (ParentPathID = 0)
UNION ALL
SELECT ChildPaths.PathID, ChildPaths.ParentPathID, ChildPaths.VersionID, CONVERT(varchar(128), Parent.Path + '/' + ChildPaths.Path) AS Path
FROM dbo.Paths AS ChildPaths
INNER JOIN Parent ON Parent.PathID = ChildPaths.ParentPathID)
SELECT PathID, ParentPathID, VersionID, Path
FROM Parent
Спасибо