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

Откуда:
Сообщений: 14
Всем доброго времени суток.
Имею такой ситуэйшин.

сразу привожу скрипты:

Таблица 1: 37987 записей, 4 мб данных.
+
CREATE TABLE [dbo].[COM_SAT]
(
[FNORAD] [int] NOT NULL,
[F_COSPAR] AS (case when [fyear] IS NULL AND [flaunch] IS NULL AND [fpiece] IS NULL then NULL else ((CONVERT([nvarchar](10),coalesce([FYEAR],''),(0))+'-')+right('000'+CONVERT([varchar](10),coalesce([FLAUNCH],''),(0)),(3)))+coalesce([FPIECE],'') end) PERSISTED,
[FLASTNAME] [varchar] (70) COLLATE Cyrillic_General_CI_AS NULL,
[FCLASS] [varchar] (1) COLLATE Cyrillic_General_CI_AS NULL,
[FYEAR] [int] NULL,
[FLAUNCH] [int] NULL,
[FPIECE] [varchar] (3) COLLATE Cyrillic_General_CI_AS NULL,
[FLAUNCHED] [date] NULL,
[FDECAYED] [date] NULL,
[FORG] [int] NULL,
[FTYPE] [int] NULL,
[FDESCR] [nvarchar] (255) COLLATE Cyrillic_General_CI_AS NULL,
[FMASSLNCH] [int] NULL,
[FMASSDRY] [nvarchar] (50) COLLATE Cyrillic_General_CI_AS NULL,
[FUSE] [nvarchar] (100) COLLATE Cyrillic_General_CI_AS NULL,
[FPURPOSE] [nvarchar] (100) COLLATE Cyrillic_General_CI_AS NULL,
[FLIFETIME] [nvarchar] (50) COLLATE Cyrillic_General_CI_AS NULL,
[FPOWER] [nvarchar] (100) COLLATE Cyrillic_General_CI_AS NULL,
[FCONTRACTOR] [nvarchar] (512) COLLATE Cyrillic_General_CI_AS NULL,
[FCONTRACTORCNTRY] [nvarchar] (100) COLLATE Cyrillic_General_CI_AS NULL,
[FLAUNCHSITE] [nvarchar] (512) COLLATE Cyrillic_General_CI_AS NULL,
[FLAUNCHVEHICLE] [nvarchar] (512) COLLATE Cyrillic_General_CI_AS NULL,
[FCOMMENT] [nvarchar] (max) COLLATE Cyrillic_General_CI_AS NULL,
[FTRAN] [int] NOT NULL,
[FWID] [int] NOT NULL IDENTITY(1, 1)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[COM_SAT] ADD CONSTRAINT [PK_COM_SAT] PRIMARY KEY NONCLUSTERED  ([FWID]) WITH (FILLFACTOR=95, PAD_INDEX=ON) ON [INDEXES]
GO
CREATE NONCLUSTERED INDEX [IX_COSPAR] ON [dbo].[COM_SAT] ([F_COSPAR]) WITH (FILLFACTOR=95) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_DECAYED] ON [dbo].[COM_SAT] ([FDECAYED]) WITH (FILLFACTOR=95) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_LAUNCHED] ON [dbo].[COM_SAT] ([FLAUNCHED]) WITH (FILLFACTOR=95) ON [PRIMARY]
GO
CREATE UNIQUE CLUSTERED INDEX [IX_NORAD] ON [dbo].[COM_SAT] ([FNORAD]) WITH (FILLFACTOR=95, PAD_INDEX=ON, IGNORE_DUP_KEY=ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_ORG] ON [dbo].[COM_SAT] ([FORG], [FWID]) WITH (FILLFACTOR=95) ON [INDEXES]
GO
CREATE NONCLUSTERED INDEX [IX_TRAN] ON [dbo].[COM_SAT] ([FTRAN], [FWID]) WITH (FILLFACTOR=95, PAD_INDEX=ON) ON [INDEXES]
GO
CREATE NONCLUSTERED INDEX [IX_TYPE] ON [dbo].[COM_SAT] ([FTYPE]) INCLUDE ([FDECAYED], [FLASTNAME], [FLAUNCH], [FLAUNCHED], [FNORAD], [FORG], [FPIECE], [FWID], [FYEAR]) WITH (FILLFACTOR=95, PAD_INDEX=ON) ON [INDEXES]
GO
ALTER TABLE [dbo].[COM_SAT] ADD CONSTRAINT [FK_COM_SAT_COM_ORGS] FOREIGN KEY ([FORG]) REFERENCES [dbo].[COM_ORGS] ([FWID])
GO
ALTER TABLE [dbo].[COM_SAT] ADD CONSTRAINT [FK_COM_SAT_COM_TRAN] FOREIGN KEY ([FTRAN]) REFERENCES [dbo].[COM_TRAN] ([FWID])
GO
ALTER TABLE [dbo].[COM_SAT] ADD CONSTRAINT [FK_COM_SAT_COM_TYPE] FOREIGN KEY ([FTYPE]) REFERENCES [dbo].[COM_TYPE] ([FWID])
GO
GRANT UPDATE ([FDESCR]) ON [dbo].[COM_SAT] TO [public]


Таблица 2: 82425126 записей, 26 гб данных. (основное хранилище)
+
CREATE TABLE [dbo].[COM_TLE]
(
[FUPDATE] [datetime2] (0) NOT NULL,
[FTLE0] [varchar] (70) COLLATE Cyrillic_General_CI_AS NULL,
[FTLE1] [varchar] (70) COLLATE Cyrillic_General_CI_AS NULL,
[FTLE2] [varchar] (70) COLLATE Cyrillic_General_CI_AS NULL,
[FSAT] [int] NOT NULL,
[FTRAN] [int] NOT NULL,
[FWID] [int] NOT NULL IDENTITY(1, 1),
[FDAY] [decimal] (11, 8) NULL,
[FSETTYPE] [varchar] (1) COLLATE Cyrillic_General_CI_AS NULL,
[FSETNUMBER] [smallint] NULL,
[FCHECKSUM1] [tinyint] NULL,
[FCHECKSUM2] [tinyint] NULL,
[FINCLINATION] [decimal] (7, 4) NULL,
[FRANODE] [decimal] (7, 4) NULL,
[FECCENTRICITY] [decimal] (8, 7) NULL,
[FARGPERIGEE] [decimal] (7, 4) NULL,
[FMEANANOMALY] [decimal] (7, 4) NULL,
[FMEANMOTION] [decimal] (10, 8) NULL,
[FMEANVELOCITY] [decimal] (10, 8) NULL,
[F1DERIV] [decimal] (8, 8) NULL,
[F2DERIV] [float] NULL,
[FBSTAR] [float] NULL,
[FPERIGEE] [decimal] (12, 4) NULL,
[FAPOGEE] [decimal] (12, 4) NULL,
[FORBITLEN] [decimal] (12, 4) NULL,
[FREVNUMBER] [int] NULL,
[FSEMIMAJOR] AS (CONVERT([decimal](12,4),power(square((((86400)/[FMEANMOTION])/(2))/pi())*(398600441800000.),(1.0)/(3))/(1000),0)) PERSISTED,
[FSEMIMINOR] AS (CONVERT([decimal](12,4),(power(square((((86400)/[FMEANMOTION])/(2))/pi())*(398600441800000.),(1.0)/(3))*sqrt((1)-square([FECCENTRICITY])))/(1000),0)) PERSISTED,
[F_YEAR] AS (datepart(year,[FUPDATE])) PERSISTED
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[COM_TLE] ADD CONSTRAINT [PK_COM_TLE] PRIMARY KEY NONCLUSTERED  ([FWID]) WITH (FILLFACTOR=85) ON [INDEXES]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_DAY] ON [dbo].[COM_TLE] ([FSAT], [F_YEAR], [FDAY]) WITH (FILLFACTOR=95, IGNORE_DUP_KEY=ON) ON [INDEXES]
GO
CREATE UNIQUE CLUSTERED INDEX [IX_SAT] ON [dbo].[COM_TLE] ([FSAT], [FUPDATE], [FTRAN]) WITH (FILLFACTOR=95, PAD_INDEX=ON, IGNORE_DUP_KEY=ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_UPDATE] ON [dbo].[COM_TLE] ([FUPDATE]) WITH (FILLFACTOR=95) ON [INDEXES]
GO
CREATE STATISTICS [FTRAN] ON [dbo].[COM_TLE] ([FTRAN])
GO
ALTER TABLE [dbo].[COM_TLE] ADD CONSTRAINT [FK_COM_TLE_COM_SAT] FOREIGN KEY ([FSAT]) REFERENCES [dbo].[COM_SAT] ([FWID])
GO
ALTER TABLE [dbo].[COM_TLE] ADD CONSTRAINT [FK_COM_TLE_COM_TRAN] FOREIGN KEY ([FTRAN]) REFERENCES [dbo].[COM_TRAN] ([FWID])
GO


Таблица 3: 6294 записей, 1 мб данных. (журнал закачек данных)
+
CREATE TABLE [dbo].[COM_TRAN]
(
[FDATE] [datetime] NOT NULL,
[FCOUNT] [int] NULL,
[FSOURCE] [int] NOT NULL,
[FDEST] [int] NOT NULL,
[FDESCR] [nvarchar] (255) COLLATE Cyrillic_General_CI_AS NULL,
[FWID] [int] NOT NULL IDENTITY(1, 1)
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[COM_TRAN] ADD CONSTRAINT [PK_COM_TRAN] PRIMARY KEY CLUSTERED  ([FWID]) WITH (FILLFACTOR=90) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_COUNT] ON [dbo].[COM_TRAN] ([FCOUNT], [FSOURCE]) INCLUDE ([FWID]) WITH (FILLFACTOR=90) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_DATE] ON [dbo].[COM_TRAN] ([FDATE], [FDEST]) INCLUDE ([FCOUNT], [FDESCR]) WITH (FILLFACTOR=90) ON [INDEXES]
GO
CREATE NONCLUSTERED INDEX [IX_DESTSRC] ON [dbo].[COM_TRAN] ([FDEST], [FWID]) WITH (FILLFACTOR=90) ON [INDEXES]
GO
CREATE NONCLUSTERED INDEX [IX_SRCDEST] ON [dbo].[COM_TRAN] ([FSOURCE], [FWID]) WHERE ([FCOUNT]<>(0)) WITH (FILLFACTOR=90) ON [INDEXES]
GO
CREATE NONCLUSTERED INDEX [w] ON [dbo].[COM_TRAN] ([FWID], [FSOURCE]) WITH (FILLFACTOR=85) ON [PRIMARY]
GO
CREATE STATISTICS [FSOURCE] ON [dbo].[COM_TRAN] ([FSOURCE])
GO
ALTER TABLE [dbo].[COM_TRAN] ADD CONSTRAINT [FK_COM_TRAN_COM_DATADST] FOREIGN KEY ([FDEST]) REFERENCES [dbo].[COM_DATADST] ([FWID])
GO
ALTER TABLE [dbo].[COM_TRAN] ADD CONSTRAINT [FK_COM_TRAN_COM_SOURCES] FOREIGN KEY ([FSOURCE]) REFERENCES [dbo].[COM_SOURCES] ([FWID])
GO


в таблицу 1 данные приходят 0-10 строк в неделю, во 2-ю – 15000-20000 в день, в 3-ю - десяток в день.
поэтому обвешаны индексами прилично, и в принципе быстродействие вставки не волнует, разве размер базы..

написал запрос:
declare @tmp_tran table
(
	fwid int primary key
)
insert into @tmp_tran
select fwid from COM_TRAN
where fsource = @src
	and fcount <> 0

SELECT
	TLE.FTLE0 + CHAR(13) + CHAR(10) + TLE.FTLE1 + CHAR(13) + CHAR(10) + TLE.FTLE2 AS FTLE,
	SAT.FNORAD,
	TLE.FUPDATE
FROM COM_SAT SAT
	CROSS APPLY
		(SELECT TOP 1 FUPDATE, FTLE0, FTLE1, FTLE2, FSAT, FTRAN
		FROM COM_TLE T
			INNER JOIN @tmp_tran TR on TR.FWID = T.FTRAN
		WHERE T.FUPDATE <= GETDATE()
			AND T.FSAT = SAT.FWID
		ORDER BY FUPDATE DESC) TLE
WHERE 1 = 1
	AND SAT.FDECAYED IS NULL

Ним выбираются последние данные (свежесть определяется полем FUPDATE) на какую-то дату, в данном случае, на текущий момент.
Выбирается последняя строка из com_tle по каждому элементу из com_sat, при этом джойнимся с com_tran, в которой фильтруется код источника данных, чтобы получить последние данные по такому-то коду (обращаю внимание – не найти последние и среди найденного найти по нужному коду, а найти все последние по такому то коду).

Сейчас в запросе стоит @таблица, пробывал с временной таблицей с индексом по единственному полю, пробывал также подставлять непосредственно основную таблицу с доп-условием.
Были варианты сделать через оконную функцию, но нумеровать такое количество строк долго, поэтому CROSS APPLY отлично подходит.

В чем проблема – имеется десяток кодов источников. распределение очень нелинейное. например, по коду 1 – 90% всех записей, по коду 3 – 0.1%. Когда запросу скармливаем код 1, он честно возвращает ~15000 строк за несколько секунд, когда код 3 – может длиться 8-9-10 минут, и возвращает ~300 строк.

Планы одинаковые:
+
  |--Hash Match(Inner Join, HASH:([ORG].[FWID])=([SAT].[FORG]), RESIDUAL:([orbital].[dbo].[COM_SAT].[FORG] as [SAT].[FORG]=[orbital].[dbo].[COM_ORGS].[FWID] as [ORG].[FWID]))
       |--Clustered Index Scan(OBJECT:([orbital].[dbo].[COM_ORGS].[PK_COM_COUNTRIES] AS [ORG]))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([SAT].[FWID]))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([TYP].[FWID]))
            |    |--Clustered Index Scan(OBJECT:([orbital].[dbo].[COM_TYPE].[PK_COM_TYPE] AS [TYP]))
            |    |--Index Seek(OBJECT:([orbital].[dbo].[COM_SAT].[IX_TYPE] AS [SAT]), SEEK:([SAT].[FTYPE]=[orbital].[dbo].[COM_TYPE].[FWID] as [TYP].[FWID]),  WHERE:([orbital].[dbo].[COM_SAT].[FDECAYED] as [SAT].[FDECAYED] IS NULL) ORDERED FORWARD)
            |--Top(TOP EXPRESSION:((1)))
                 |--Nested Loops(Inner Join, OUTER REFERENCES:([T].[FTRAN]))
                      |--Compute Scalar(DEFINE:([Expr1011]=((((([orbital].[dbo].[COM_TLE].[FTLE0] as [T].[FTLE0]+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE1] as [T].[FTLE1])+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE2] as [T].[FTLE2]))
                      |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1014], [Expr1015], [Expr1013]))
                      |         |--Compute Scalar(DEFINE:(([Expr1014],[Expr1015],[Expr1013])=GetRangeWithMismatchedTypes(NULL,CONVERT_IMPLICIT(datetime2(3),getdate(),0),(42))))
                      |         |    |--Constant Scan
                      |         |--Clustered Index Seek(OBJECT:([orbital].[dbo].[COM_TLE].[IX_SAT] AS [T]), SEEK:([T].[FSAT]=[orbital].[dbo].[COM_SAT].[FWID] as [SAT].[FWID] AND [T].[FUPDATE] > [Expr1014] AND [T].[FUPDATE] < [Expr1015]) ORDERED BACKWARD)
                      |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[#tmp_tran] AS [TR]), SEEK:([TR].[fwid]=[orbital].[dbo].[COM_TLE].[FTRAN] as [T].[FTRAN]) ORDERED FORWARD)


statistics io on:
+

Код 1:
(строк обработано: 15515)
Таблица "Worktable". Число просмотров 0, логических чтений 0, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TRAN". Число просмотров 0, логических чтений 91794, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TLE". Число просмотров 16477, логических чтений 67299, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_SAT". Число просмотров 3, логических чтений 288, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TYPE". Число просмотров 1, логических чтений 2, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_ORGS". Число просмотров 1, логических чтений 3, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.

Код 3: (почему столько чтений вдруг стало?)
(строк обработано: 328)
Таблица "Worktable". Число просмотров 0, логических чтений 0, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TRAN". Число просмотров 0, логических чтений 145189647, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TLE". Число просмотров 16477, логических чтений 2991453, физических чтений 61761, упреждающих чтений 2744065, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_SAT". Число просмотров 3, логических чтений 288, физических чтений 262, упреждающих чтений 227, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TYPE". Число просмотров 1, логических чтений 2, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_ORGS". Число просмотров 1, логических чтений 3, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.


Microsoft SQL Server 2008 R2 (RTM) - 10.50.1765.0 (X64) 
	Feb  2 2011 17:33:22 
	Copyright (c) Microsoft Corporation
	Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: )

Напоследок также спрошу :)
Бывает также, что и с кодом 1 селектится около 1-1.5 минуты, после чего снова быстро. Отключал автообновление статистики, поведение не изменялось. Кешируется как-то?
12 окт 11, 21:32    [11430057]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31990
NetAnton
Планы одинаковые:
Что то у вас план не соответствует запросу. Так можно долго искать причину :-)

Вы прям приведите планы и статистику для того запроса, который здесь написали.
12 окт 11, 22:15    [11430260]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31990
alexeyvg
Вы прям приведите планы и статистику для того запроса, который здесь написали.
Да, и для обоих кодов!
12 окт 11, 22:15    [11430262]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
прошу пардону.. я его и в процедуру успел засунуть, чтоб менялся только параметр :)
щас перевыполню с подстановкой таблицы, безо всяких временных.. на лицо те же замеры, проще для понимания..
12 окт 11, 22:22    [11430286]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Итак, код 1: 1,5 мин, второй раз и дальше - меньше секунды.
+
  |--Nested Loops(Inner Join, OUTER REFERENCES:([SAT].[FWID]))
       |--Index Scan(OBJECT:([orbital].[dbo].[COM_SAT].[IX_TYPE] AS [SAT]),  WHERE:([orbital].[dbo].[COM_SAT].[FDECAYED] as [SAT].[FDECAYED] IS NULL))
       |--Top(TOP EXPRESSION:((1)))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([T].[FTRAN], [Expr1011]) WITH ORDERED PREFETCH)
                 |--Compute Scalar(DEFINE:([Expr1006]=((((([orbital].[dbo].[COM_TLE].[FTLE0] as [T].[FTLE0]+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE1] as [T].[FTLE1])+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE2] as [T].[FTLE2]))
                 |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1009], [Expr1010], [Expr1008]))
                 |         |--Compute Scalar(DEFINE:(([Expr1009],[Expr1010],[Expr1008])=GetRangeWithMismatchedTypes(NULL,CONVERT_IMPLICIT(datetime2(3),getdate(),0),(42))))
                 |         |    |--Constant Scan
                 |         |--Clustered Index Seek(OBJECT:([orbital].[dbo].[COM_TLE].[IX_SAT] AS [T]), SEEK:([T].[FSAT]=[orbital].[dbo].[COM_SAT].[FWID] as [SAT].[FWID] AND [T].[FUPDATE] > [Expr1009] AND [T].[FUPDATE] < [Expr1010]) ORDERED BACKWARD)
                 |--Index Seek(OBJECT:([orbital].[dbo].[COM_TRAN].[w] AS [TR]), SEEK:([TR].[FWID]=[orbital].[dbo].[COM_TLE].[FTRAN] as [T].[FTRAN] AND [TR].[FSOURCE]=(1)) ORDERED FORWARD)

(строк обработано: 15516)
Таблица "COM_TRAN". Число просмотров 0, логических чтений 91905, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TLE". Число просмотров 16477, логических чтений 67300, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_SAT". Число просмотров 1, логических чтений 282, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.


Код 3: (11 минут)
+
  |--Nested Loops(Inner Join, OUTER REFERENCES:([SAT].[FWID]))
       |--Index Scan(OBJECT:([orbital].[dbo].[COM_SAT].[IX_TYPE] AS [SAT]),  WHERE:([orbital].[dbo].[COM_SAT].[FDECAYED] as [SAT].[FDECAYED] IS NULL))
       |--Top(TOP EXPRESSION:((1)))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([T].[FTRAN], [Expr1011]) WITH ORDERED PREFETCH)
                 |--Compute Scalar(DEFINE:([Expr1006]=((((([orbital].[dbo].[COM_TLE].[FTLE0] as [T].[FTLE0]+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE1] as [T].[FTLE1])+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE2] as [T].[FTLE2]))
                 |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1009], [Expr1010], [Expr1008]))
                 |         |--Compute Scalar(DEFINE:(([Expr1009],[Expr1010],[Expr1008])=GetRangeWithMismatchedTypes(NULL,CONVERT_IMPLICIT(datetime2(3),getdate(),0),(42))))
                 |         |    |--Constant Scan
                 |         |--Clustered Index Seek(OBJECT:([orbital].[dbo].[COM_TLE].[IX_SAT] AS [T]), SEEK:([T].[FSAT]=[orbital].[dbo].[COM_SAT].[FWID] as [SAT].[FWID] AND [T].[FUPDATE] > [Expr1009] AND [T].[FUPDATE] < [Expr1010]) ORDERED BACKWARD)
                 |--Index Seek(OBJECT:([orbital].[dbo].[COM_TRAN].[w] AS [TR]), SEEK:([TR].[FWID]=[orbital].[dbo].[COM_TLE].[FTRAN] as [T].[FTRAN] AND [TR].[FSOURCE]=(3)) ORDERED FORWARD)

(строк обработано: 481)
Таблица "COM_TRAN". Число просмотров 0, логических чтений 145196393, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TLE". Число просмотров 16477, логических чтений 2988793, физических чтений 32059, упреждающих чтений 2793812, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_SAT". Число просмотров 1, логических чтений 282, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.


Ну и для полноты картины, код 8: (18 сек, затем меньше 1)
+
  |--Nested Loops(Inner Join, OUTER REFERENCES:([SAT].[FWID]))
       |--Index Scan(OBJECT:([orbital].[dbo].[COM_SAT].[IX_TYPE] AS [SAT]),  WHERE:([orbital].[dbo].[COM_SAT].[FDECAYED] as [SAT].[FDECAYED] IS NULL))
       |--Top(TOP EXPRESSION:((1)))
            |--Nested Loops(Inner Join, OUTER REFERENCES:([T].[FTRAN], [Expr1011]) WITH ORDERED PREFETCH)
                 |--Compute Scalar(DEFINE:([Expr1006]=((((([orbital].[dbo].[COM_TLE].[FTLE0] as [T].[FTLE0]+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE1] as [T].[FTLE1])+' ')+' ')+[orbital].[dbo].[COM_TLE].[FTLE2] as [T].[FTLE2]))
                 |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1009], [Expr1010], [Expr1008]))
                 |         |--Compute Scalar(DEFINE:(([Expr1009],[Expr1010],[Expr1008])=GetRangeWithMismatchedTypes(NULL,CONVERT_IMPLICIT(datetime2(3),getdate(),0),(42))))
                 |         |    |--Constant Scan
                 |         |--Clustered Index Seek(OBJECT:([orbital].[dbo].[COM_TLE].[IX_SAT] AS [T]), SEEK:([T].[FSAT]=[orbital].[dbo].[COM_SAT].[FWID] as [SAT].[FWID] AND [T].[FUPDATE] > [Expr1009] AND [T].[FUPDATE] < [Expr1010]) ORDERED BACKWARD)
                 |--Index Seek(OBJECT:([orbital].[dbo].[COM_TRAN].[w] AS [TR]), SEEK:([TR].[FWID]=[orbital].[dbo].[COM_TLE].[FTRAN] as [T].[FTRAN] AND [TR].[FSOURCE]=(8)) ORDERED FORWARD)

(строк обработано: 14915)
Таблица "COM_TRAN". Число просмотров 0, логических чтений 585084, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_TLE". Число просмотров 16477, логических чтений 77711, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "COM_SAT". Число просмотров 1, логических чтений 282, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.


Распределение:
1	80 075 018
3	31 420
8	2 059 691

Не вижу логики в количестве чтений... там где строк в таблице меньше, чтений реально больше.. в 3-м вообще запредел...
Планы сравнивалкой прошел - отличаются только числом в [TR].[FSOURCE]=(8).
12 окт 11, 22:41    [11430336]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
Glory
Member

Откуда:
Сообщений: 104751
А можно не предаврительные планы, а реальные ?
С числом выполнений каждой операции, числом обработанных записей и тд
12 окт 11, 22:48    [11430360]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Реальные планы :)

К сообщению приложен файл (profile.rar - 4Kb) cкачать
12 окт 11, 23:10    [11430414]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31990
NetAnton,

А если на такое заменить?

SELECT
	TLE.FTLE0 + CHAR(13) + CHAR(10) + TLE.FTLE1 + CHAR(13) + CHAR(10) + TLE.FTLE2 AS FTLE,
	SAT.FNORAD,
	TLE.FUPDATE
FROM COM_SAT SAT
	JOIN COM_TLE TLE
		ON TLE.FSAT = SAT.FWID
	JOIN (
		SELECT TOP 1 T.FWID
		FROM COM_TLE T
			INNER JOIN @tmp_tran TR on TR.FWID = T.FTRAN
		WHERE T.FUPDATE <= GETDATE()
		ORDER BY T.FUPDATE DESC
		) TLE1
		ON TLE1.FWID = TLE.FWID
WHERE 1 = 1
	AND SAT.FDECAYED IS NULL
12 окт 11, 23:43    [11430557]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31990
NetAnton
Не вижу логики в количестве чтений... там где строк в таблице меньше, чтений реально больше..
У вас больше количество строк в COM_TLE для введённого кода.
Просто для таких данных нужен другой планЮ, а ервер не понимает... Или индекс нужен другой, надо подумать.
12 окт 11, 23:47    [11430575]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
alexeyvg
У вас больше количество строк в COM_TLE для введённого кода.[/quot]
Так вроде бы наоборот :)

Запрос выполнил. Возвращает всегда одну строчку, не хватает чего-то наподобии GROUP BY по каждому SAT.

К сообщению приложен файл (plan.txt - 22Kb) cкачать
13 окт 11, 06:31    [11431059]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Я так понимаю, получается так. По каждому элементу отбирается отсортированный по дате DESC набор типа:
+
1
1
8
1
1
1
1
1
1
1
1
1
3
1
1
1
8

С учетом распределения где то так. И затем серверу необходимо найти первую запись с нужным кодом, а т.к. 1-го у нас >90%, поэтому и находятся такие записи быстрее.. 8-й похуже, 2.5%, ищется медленнее, лопатит больше записей, но не настолько катастрофически.
3-й встречается редко, поэтому и выплывает отсюда такая скорость поиска.. это мы только один элемент обработали.

Кстати, почему 8-й с такой малой долей ищется всего в ~2-3 раза медленнее (0.3 с против 0.6-0.8) из-за, того что он есть только с относительно недавнего момента (2009 или около того, причем дальше - больше). Догадываюсь, что если вместо GETDATE втулить год-второй назад, тут тоже просесть должно.

Как серверу грамотно подсказать что-либо?
13 окт 11, 07:46    [11431110]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Ну вот, поставил '2010-01-01' вместо GETDATE, подтвердилось. Число строк с 8-м кодом упало с 2.2кк до 47к, плотность упала, запрос выполняется 102 сек.
13 окт 11, 07:55    [11431119]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
С датами картина такая:
+

1:
СтрокГод
1611959
7371960
24581961
38631962
43871963
67641964
134941965
182671966
370801967
316211968
452041969
690451970
1407031971
1802491972
1995341973
1999771974
2209411975
2453231976
3446081977
4059671978
5008931979
6087961980
6515931981
6120171982
5257781983
4950561984
4975901985
6206951986
9824461987
13953601988
16495921989
16445991990
18402131991
22887891992
22655871993
23085781994
34784571995
20151301996
25717291997
26778981998
29010541999
31729412000
33572582001
33041622002
32222652003
34626182004
36970202005
38660932006
43591892007
45905132008
51905462009
48042412010
23533242011



+

3:
СтрокГод
32004
92005
26612006
53382007
54582008
70422009
64512010
44632011



+

8:
СтрокГод
11962
11972
12006
82007
152842008
317392009
2963012010
17213862011

13 окт 11, 08:00    [11431127]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
hpv
Member

Откуда:
Сообщений: 153
NetAnton,

может так?

declare @tmp_tran table
(
	ftran int primary key,
	fupdate datetime2(0)
)
insert into @tmp_tran
select tle.ftran, max(fupdate) as fupdate
	from COM_TRAN as tr
	join COM_TLE as tle on tle.ftran = tr.fwid
where tr.fsource = @src
	and tr.fcount <> 0
	and tle.fupdate <= getdate()
group by tle.ftran


SELECT
	T.FTLE0 + CHAR(13) + CHAR(10) + T.FTLE1 + CHAR(13) + CHAR(10) + T.FTLE2 AS FTLE,
	SAT.FNORAD,
	T.FUPDATE
FROM @tmp_tran as tmp 
INNER JOIN COM_TLE as T on t.ftran = tmp.ftran and t.fupdate = tmp.fupdate
INNER JOIN COM_SAT as SAT on t.FSAT = SAT.FWID
WHERE 1 = 1 AND SAT.FDECAYED IS NULL
13 окт 11, 11:17    [11432127]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
А так возвращает в разрезе строк в COM_TRAN.. т.е. имеем 1000 записей по такому-то коду в журнале загрузок, оно последние строки по журналу и тянет.. ну а дальше иннер джойн с COM_SAT нового уже ничего не покажет..
Но спасибо за вариант :)
13 окт 11, 11:41    [11432384]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Сделал GROUP BY то что надо, теперь ситуация противоположная, и куда более логичная :) 3-й код выбирает быстро, остальные лопатит долго. Для худшего случая выполняется аггрегация 80кк строк.. Подумаю над вариантами оптимизации.
13 окт 11, 11:53    [11432530]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Пришла мысля об секционировании таблицы.
В целом запрашиваются либо все данные по какому то обьекту com_sat, либо по всем ним на какую то дату, чаще всего - настоящее время. + куча фильтров и джойнов.
Я так понимаю, если грамотно задать диапазоны секций, чтобы в каждой из них было по 2-3-5кк записей, то запрос по всем обьектам будет шуршать в основном по какой то одной секции. Разве если только не укажут дату рядом с границей секций, тогда будет вылазить в соседнюю.. Ну и учесть факт, что последние данные по особо древним обьектам могут быть старые, тут может пойти лезть во все секции.. Хотя, есть доп-фильтр типа "трогать/не трогать старые", и если их таки трогают, то сами знают, что лезут в архив, подождут :)
13 окт 11, 12:38    [11433049]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31990
NetAnton
Пришла мысля об секционировании таблицы.
В целом запрашиваются либо все данные по какому то обьекту com_sat, либо по всем ним на какую то дату, чаще всего - настоящее время. + куча фильтров и джойнов.
Я так понимаю, если грамотно задать диапазоны секций, чтобы в каждой из них было по 2-3-5кк записей, то запрос по всем обьектам будет шуршать в основном по какой то одной секции. Разве если только не укажут дату рядом с границей секций, тогда будет вылазить в соседнюю.. Ну и учесть факт, что последние данные по особо древним обьектам могут быть старые, тут может пойти лезть во все секции.. Хотя, есть доп-фильтр типа "трогать/не трогать старые", и если их таки трогают, то сами знают, что лезут в архив, подождут :)
Эффект будет такой же, как добавить дату в запросе (ну и поменять индексы).
13 окт 11, 15:56    [11435114]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Дата в запросе и так есть :) tle.FUPDATE.
Но с секциями он не должен лезть в пространство данных, которое ему не надо, соответственно как-будто работаем с меньшей таблицей. Я неправ?
А иначе придумаю компромисс какой-то..
13 окт 11, 16:22    [11435435]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
PVC
Member

Откуда:
Сообщений: 319
NetAnton,
а если так?

declare @dt date = getdate()
....
and tle.fupdate <=@dt
....

?
13 окт 11, 17:54    [11436599]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Не помогло :(

Подумываю денормализовать маленько структуру и добавить поле fsource непосредственно, чтоб не джойнить таблицу. Ну и в кластерный индекс добавить его..
На меньшей копии таблицы показывает хорошие результаты..
13 окт 11, 18:01    [11436664]     Ответить | Цитировать Сообщить модератору
 Re: План одинаковый, данных меньше, а время больше  [new]
NetAnton
Member

Откуда:
Сообщений: 14
Как будет лучше всего в случае денормализации за целостностью смотреть? Триггер шлепнуть или при вставках вручную обновлять :) NOT NULL будет как минимум
13 окт 11, 18:03    [11436683]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить