Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите пожалуйста с запросом!  [new]
momtaing
Member

Откуда:
Сообщений: 1
Есть два запроса которые выбирают одни и те же данные

первый работает просто прекрасно (время выполнения 31 с.)
SELECT DISTINCT
a.AccountNumber
, LTRIM(RTRIM(pp.LastName+ ' '+pp.FirstName+ ' '+pp.SecondName)) AS abon
, eps.TsName
, eps.LvlName
, eps.TowerNumber
--, tg.ShortName
, a.AccountId
, p.PointId
--, t.IsHeating
INTO #opal
FROM AccountingCommon.Account a
JOIN AccountingCommon.PhysicalPerson pp ON a.PhysicalPersonId = pp.PhysicalPersonId
JOIN AccountingCommon.UsageObject acuo ON acuo.AccountId = a.AccountId
JOIN AccountingCommon.Point p ON p.UsageObjectId = acuo.UsageObjectId
JOIN SupportDefined.ElectricPowerSource eps ON eps.TowerId = p.OblElementId
JOIN FinanceMain.Operation o ON o.AccountId = a.AccountId
JOIN FinanceMain.OperationRow o1 ON o1.OperationId = o.OperationId
JOIN Dictionary.Tariff t ON o1.TariffId = t.TariffId
JOIN Dictionary.TariffGroup tg ON t.TariffGroupId = tg.TariffGroupId
--LEFT JOIN Measuring.PointGroupIndex mpgi ON mpgi.PointId = p.PointId

WHERE t.IsHeating = '1' OR tg.ShortName = 'Село не газифіковані'

SELECT DISTINCT [o].*, 
CONVERT(VARCHAR(10), mpgi.Date, 104)AS DATA
,mpgi.CachedIndexes
,mpgi.PointId
FROM #opal o 
LEFT JOIN Measuring.PointGroupIndex mpgi ON mpgi.PointId = o.PointId

WHERE mpgi.Date = (SELECT MAX(mpgi.Date)FROM Measuring.PointGroupIndex mpgi
                  WHERE mpgi.PointId = o.PointId)
ORDER BY o.AccountNumber
DROP TABLE #opal


второй это по сути тот же запрос но без формирования tmp таблицы
SELECT DISTINCT
a.AccountNumber
, LTRIM(RTRIM(pp.LastName+ ' '+pp.FirstName+ ' '+pp.SecondName)) AS abon
, eps.TsName
, eps.LvlName
, eps.TowerNumber
--, tg.ShortName
, a.AccountId
, p.PointId
,CONVERT(VARCHAR(10), mpgi.Date, 104)AS DATA
,mpgi.CachedIndexes
,mpgi.PointId
--, t.IsHeating
FROM AccountingCommon.Account a
JOIN AccountingCommon.PhysicalPerson pp ON a.PhysicalPersonId = pp.PhysicalPersonId
JOIN AccountingCommon.UsageObject acuo ON acuo.AccountId = a.AccountId
JOIN AccountingCommon.Point p ON p.UsageObjectId = acuo.UsageObjectId
JOIN SupportDefined.ElectricPowerSource eps ON eps.TowerId = p.OblElementId
JOIN FinanceMain.Operation o ON o.AccountId = a.AccountId
JOIN FinanceMain.OperationRow o1 ON o1.OperationId = o.OperationId
JOIN Dictionary.Tariff t ON o1.TariffId = t.TariffId
JOIN Dictionary.TariffGroup tg ON t.TariffGroupId = tg.TariffGroupId
LEFT JOIN Measuring.PointGroupIndex mpgi ON mpgi.PointId = p.PointId

WHERE t.IsHeating = '1' OR tg.ShortName = 'Село не газифіковані'
AND mpgi.Date = (SELECT MAX(mpgi.Date)FROM Measuring.PointGroupIndex mpgi
                  WHERE mpgi.PointId = p.PointId)
ORDER BY a.AccountNumber


проблема в том что по быстродействию второй запрос никуда не годится... После 1:40 я его становил
Если варианты переделать этот запрос на максимальное быстродействие без временных таблиц?
15 окт 13, 17:36    [14974855]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом!  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
LEFT JOIN Measuring.PointGroupIndex mpgi ON mpgi.PointId = p.PointId

Только ли формированием временной таблицы они отличаются? Посмотрите планы запросов и статистику IO
15 окт 13, 17:42    [14974897]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом!  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31437
momtaing
Если варианты переделать этот запрос на максимальное быстродействие без временных таблиц?
Нужно смотреть планы, обновлять статистику, может, делать подсказки, можно попробовать указать рекомпиляцию запроса...

Можно посмотреть план второго запроса с временной таблицей, как там цепляется Measuring.PointGroupIndex, и попробовать в запросе без временной таблицы указать такое же соединение подсказкой.

Да, иногда сиквел не может построить такой оптимальный план, какой делаете вы сами, разбивая запрос на 2.

В вашем случае всё хорошо, решается разбиением, но это не всегда помогает, потому что для разных значений параметров в условиях оптимальные планы разные :-(
15 окт 13, 17:51    [14974946]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом!  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31437
momtaing
LEFT JOIN Measuring.PointGroupIndex mpgi ON mpgi.PointId = p.PointId
Вообще у вас по факту INNER JOIN, слово LEFT немного запутывает ситуацию.

Кроме того, если версия позволяет, я бы переделал эту конструкцию с Measuring.PointGroupIndex на outer apply
15 окт 13, 17:58    [14974987]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить