Оптимизация SQL-запроса с помощью Union All

У меня есть запрос с 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

Спасибо


person Coesy    schedule 09.11.2010    source источник
comment
недостаточно информации для ответа...   -  person Mitch Wheat    schedule 09.11.2010
comment
Предположительно, ваши представления содержат соединения. Представление без объединений имеет небольшую ценность (это таблица!), за исключением, возможно, определенных обстоятельств, таких как скрытие столбцов (авторизация).   -  person Mitch Wheat    schedule 09.11.2010
comment
Извините, вы правы, я почищу SQL и опубликую как можно скорее.   -  person Coesy    schedule 09.11.2010
comment
Этот комментарий немного широк, Митч. Представление, которое разделяет ваши данные по горизонтали, очень ценно с точки зрения производительности. Точно так же я все время поворачиваю и развожу данные в представлениях для использования в электронных таблицах, связанных с odbc.   -  person DataWriter    schedule 09.11.2010
comment
@Coesy: Отлично, но где определения представлений?   -  person OMG Ponies    schedule 09.11.2010
comment
@OMG пони, добавлено сейчас, извините   -  person Coesy    schedule 09.11.2010


Ответы (3)


... это довольно сложные запросы на выбор, но соединения не задействованы, они фактически выбирают из двух разных представлений.

Но есть ли соединения в представлениях? И есть ли у представлений общие таблицы?

Не видя запроса и запросов, которые замещают представления, очень мало кто может предоставить что-либо ценное.

person OMG Ponies    schedule 09.11.2010

«Расчетная стоимость поддерева» составляет 2,12357, я всегда предполагал, что если она больше 1, то это довольно медленный запрос.

Стоимость поддерева не может использоваться независимо для оценки производительности. Он предназначен для использования для сравнения различных запросов, выполняющих одну и ту же задачу. Таким образом, неверно предполагать, что высокая стоимость указывает на низкую производительность запроса.

Вы должны ответить на вопрос «Возвращает ли запрос результаты за приемлемое время?»

С учетом всего сказанного, и чтобы ослабить риторику, более высокая стоимость поддерева может поддержать вашу мысль о том, что возможно запрос можно улучшить.

нет сканирования таблиц, только сканирование кластеризованного индекса

Что может быть большей возможностью для улучшения запроса, так это посмотреть, почему существует сканирование кластеризованного индекса. Сканирование кластеризованного индекса эквивалентно сканированию таблицы. Сканируется весь кластеризованный индекс, включая данные таблицы. Должны ли оцениваться все строки в таблице, или это указывает на возможность повышения производительности?

person bobs    schedule 09.11.2010

Запустите запрос с помощью мастера настройки индексов, и это может сказать вам, какие индексы могут помочь.

На самом деле было бы лучше проанализировать и определить улучшения sql, но вы не разместили sql, поэтому мы не можем вам в этом помочь.

person Samuel Neff    schedule 09.11.2010