Я ищу способ оптимизации запроса SELECT с левым соединением между таблицей измерения даты и таблицей фактов, которая должна отображать сумму меры за 2014 год.Медленный запрос в SQL Server с левым соединением
Вот запрос:
select SUM(coalesce(f.NBSCANS,0)) as somme
from DIM_DATE as d
left join FCT_SCAN as f
on d.DATE = CAST(f.DATE_HEURE as DATE)
and CAST(d.HEURE as varchar(4)) = CAST(CAST(f.DATE_HEURE as time) as varchar(4))
where d.ANNEE = 2014
Этот запрос слишком медленно, потому что я никогда не видел результатов. Если я добавлю предложение WHERE в месяц (например: d.MOIS = 11), требуется 1 минута (так немного).
Но если добавить ИНЕКЕ в день тоже, как это результаты отображаются в 4 секунды:
select SUM(coalesce(f.NBSCANS,0)) as somme
from DIM_DATE as d
left join FCT_SCAN as f
on d.DATE = CAST(f.DATE_HEURE as DATE)
and CAST(d.HEURE as varchar(4)) = CAST(CAST(f.DATE_HEURE as time) as varchar(4))
where d.ANNEE = 2014
and d.MOIS = 11
and d.JOUR = 5
Для информации, здесь являются CREATE TABLE Сценарий DIM_DATE:
CREATE TABLE [dbo].[DIM_DATE](
[DATE_HEURE] [datetime] NOT NULL,
[ANNEE] [int] NULL,
[MOIS] [int] NULL,
[JOUR] [int] NULL,
[DATE] [date] NULL,
[JOUR_SEM_DATE] [varchar](10) NULL,
[NUM_JOUR_SEM_DATE] [int] NULL,
[HEURE] [time](0) NULL,
[TRANCHE_1H] [time](0) NULL,
[TRANCHE_DEMIH] [time](0) NULL,
[TRANCHE_QUARTH] [time](0) NULL,
[TRANCHE_10M] [time](0) NULL,
CONSTRAINT [PK_DIM_DATE] PRIMARY KEY NONCLUSTERED
(
[DATE_HEURE] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Поле DATE_HEURE в FCT_SCAN такое же, что и в DIM_DATE.
В DIM_DATE есть запись через каждые 10 минут:
DATE_HEURE
2015-06-17 12:00:00.000
2015-06-17 12:10:00.000
2015-06-17 12:20:00.000
2015-06-17 12:30:00.000
2015-06-17 12:40:00.000
2015-06-17 12:50:00.000
2015-06-17 13:00:00.000
2015-06-17 13:10:00.000
2015-06-17 13:20:00.000
2015-06-17 13:30:00.000
Так что мой вопрос заключается в следующем: как оптимизировать этот запрос, зная, что я должен держать LEFT JOIN? (для пакета Cognos)
Редактировать: Вот план выполнения.
|--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [globalagg1013]=(0) THEN NULL ELSE [globalagg1015] END))
|--Stream Aggregate(DEFINE:([globalagg1013]=SUM([partialagg1012]), [globalagg1015]=SUM([partialagg1014])))
|--Parallelism(Gather Streams)
|--Stream Aggregate(DEFINE:([partialagg1012]=COUNT_BIG([Expr1007]), [partialagg1014]=SUM([Expr1007])))
|--Compute Scalar(DEFINE:([Expr1007]=CASE WHEN [DECIS_DM_PARCOURS_PAX].[dbo].[FCT_SCAN].[NBSCANS] as [f].[NBSCANS] IS NOT NULL THEN CONVERT_IMPLICIT(int,[DECIS_DM_PARCOURS_PAX].[dbo].[FCT_SCAN].[NBSCANS] as [f].[NBSCANS],0) ELSE (0) END))
|--Nested Loops(Left Outer Join, OUTER REFERENCES:([d].[DATE], [Expr1009]))
|--Compute Scalar(DEFINE:([Expr1009]=CONVERT(varchar(4),[DECIS_DM_PARCOURS_PAX].[dbo].[DIM_DATE].[HEURE] as [d].[HEURE],121)))
| |--Table Scan(OBJECT:([DECIS_DM_PARCOURS_PAX].[dbo].[DIM_DATE] AS [d]), WHERE:([DECIS_DM_PARCOURS_PAX].[dbo].[DIM_DATE].[ANNEE] as [d].[ANNEE]=(2014)))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1003]) OPTIMIZED)
|--Compute Scalar(DEFINE:([Expr1021]=BmkToPage([Bmk1003])))
| |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1019], [Expr1020], [Expr1018]))
| |--Compute Scalar(DEFINE:(([Expr1019],[Expr1020],[Expr1018])=GetRangeThroughConvert([DECIS_DM_PARCOURS_PAX].[dbo].[DIM_DATE].[DATE] as [d].[DATE],[DECIS_DM_PARCOURS_PAX].[dbo].[DIM_DATE].[DATE] as [d].[DATE],(62))))
| | |--Constant Scan
| |--Index Seek(OBJECT:([DECIS_DM_PARCOURS_PAX].[dbo].[FCT_SCAN].[IDX_DATE_HEURE] AS [f]), SEEK:([f].[DATE_HEURE] > [Expr1019] AND [f].[DATE_HEURE] < [Expr1020]), WHERE:([DECIS_DM_PARCOURS_PAX].[dbo].[DIM_DATE].[DATE] as [d].[DATE]=CONVERT(date,[DECIS_DM_PARCOURS_PAX].[dbo].[FCT_SCAN].[DATE_HEURE] as [f].[DATE_HEURE],0) AND [Expr1009]=CONVERT(varchar(4),CONVERT(time(7),[DECIS_DM_PARCOURS_PAX].[dbo].[FCT_SCAN].[DATE_HEURE] as [f].[DATE_HEURE],0),121)) ORDERED FORWARD)
|--RID Lookup(OBJECT:([DECIS_DM_PARCOURS_PAX].[dbo].[FCT_SCAN] AS [f]), SEEK:([Bmk1003]=[Bmk1003]) LOOKUP ORDERED FORWARD)
Я подозреваю, что здесь есть петля. У меня была такая же проблема. Можете ли вы опубликовать план выполнения? Если он скажет, что соединение цикла, попытаетесь ли вы изменить «левое соединение» в «левом хеш-соединении»? –