SELECT UTC_Time, SC2
FROM Frames JOIN Science_data ON Frames.id = Science_data.id
WHERE UTC_time BETWEEN '2009-09-15 21:43:14' AND '2009-09-15 23:43:14' AND GoodToMap = 1
и
DECLARE @curTime datetime;
SET @curTime = '2009-09-15 21:43:14';
SELECT UTC_Time, SC2
FROM Frames JOIN Science_data ON Frames.id = Science_data.id
WHERE UTC_time BETWEEN @curTime AND DATEADD(hour, 2, @curTime) AND GoodToMap = 1
1й выполняется, второй уходит в перманентную задумчивость. C чем может быть связано?
Сервер MSSQL 2000 (версия 8.0.0.2040 SP4).
Если аналогичный 2му запрос выполнить но не напрямую, а через linked server — тоже всё хорошо.
Здравствуйте, amalakhov, Вы писали:
A>1й выполняется, второй уходит в перманентную задумчивость. C чем может быть связано? A>Сервер MSSQL 2000 (версия 8.0.0.2040 SP4).
А в Activity Monitor для того процесса что висит, что показывается? чего он ждет?
Надо это посмотреть, и еще есть предположение, что для второго запроса оптимизатор почему-то решает не использовать индекс по UTC_time и поэтому начинает делать full scan, что для очень большой таблицы может быть эквивалентно "перманентной задумчивости"
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>Здравствуйте, amalakhov, Вы писали:
A>>1й выполняется, второй уходит в перманентную задумчивость. C чем может быть связано? A>>Сервер MSSQL 2000 (версия 8.0.0.2040 SP4).
S>А в Activity Monitor для того процесса что висит, что показывается? чего он ждет? S>Надо это посмотреть, и еще есть предположение, что для второго запроса оптимизатор почему-то решает не использовать индекс по UTC_time и поэтому начинает делать full scan, что для очень большой таблицы может быть эквивалентно "перманентной задумчивости"
Надо посмотреть план выполнения и структуру таблицы хорошо бы увидеть.
Да и глянуть что делается в данный момент а Activity Monitor
Для начала, следует смотреть планы выполнения. Скорее всего, в первом случае, используется индекс. Во втором случае, опираясь на статистику, сервер считает что простой скан даст результат много быстрее, потому как данные отсортированы и т.п.
Решение простое, указать принудительное использование индексов.
Еще проблема может заключаться в том, что опятьтаки опираясь на статистику сиквель может выбрать определенный тип соединения , к примеру MERGE, а данных оказалось много и потому все висит (памяти мало, диск слабый). Решается указанием типа соединения.
Но все это можно легко и быстро определить посмотрев на план выполнения. Так что ждем планов!
Здравствуйте, skorpk, Вы писали: S>Надо посмотреть план выполнения и структуру таблицы хорошо бы увидеть. S>Да и глянуть что делается в данный момент а Activity Monitor
Структуры:
CREATE TABLE [dbo].[Frames](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[UTC_time] [datetime] NOT NULL,
[GoodToMap] [tinyint] NOT NULL CONSTRAINT [DF_Frames_GoodToMap] DEFAULT (0),
CONSTRAINT [PK_Frames] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Science_data](
[id] [bigint] NOT NULL,
[SC2] [binary](32) NOT NULL,
CONSTRAINT [PK_Science_data] PRIMARY KEY CLUSTERED
(
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[Science_data] WITH NOCHECK ADD CONSTRAINT [FK_Science_data_Frames] FOREIGN KEY([id])
REFERENCES [dbo].[Frames] ([id])
GO
ALTER TABLE [dbo].[Science_data] CHECK CONSTRAINT [FK_Science_data_Frames]
План выполнения — действительно сильно разные — но тут я немножко профан и не до конца могу понимать смысла нарисованного. Если подскажете, возможно ли заставить сервер выполнять 2й запрос так же как 1й, кажется это решит проблемы.
По поводу Activity Monitor — во время выполнения 2го запроса там очень много жизни, но опять же — не до конца понимаю, на что именно обращать внимание (какие столбцы имеет смысл сюда приводить). Наш процесс — 60й.
PS. Пока пост писал — 2й вариант запроса таки выполнился, заняло 8 минут (против 1 секунды)
Ну, как я Вам и написал, в первом случае сервер делает LOOP соединение, во втором HASH.
Попробуйте вот так:
DECLARE @curTime DATETIME;
SET @curTime = '2009-09-15 21:43:14';
SELECT UTC_Time,
SC2
FROM Frames
INNER LOOP JOIN Science_data
ON Frames.id = Science_data.id
WHERE UTC_time BETWEEN @curTime AND DATEADD(hour, 2, @curTime)
AND GoodToMap = 1
Уже лучше, спасибо — секунд 8 против 1, но execution plan всё равно по сравнению с 1м запросом выглядит монстрообразно
SELECT UTC_Time, SC2
FROM Frames JOIN Science_data ON Frames.id = Science_data.id
WHERE UTC_time BETWEEN '2009-09-16 21:43:14' AND '2009-09-16 23:43:14' AND GoodToMap = 1
|--Nested Loops(Inner Join, OUTER REFERENCES:([Frames].[id]) WITH PREFETCH)
|--Filter(WHERE:([Frames].[GoodToMap]=1))
| |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([LEND_FLIGHT].[dbo].[Frames]) WITH PREFETCH)
| |--Index Seek(OBJECT:([LEND_FLIGHT].[dbo].[Frames].[IX_UTC]), SEEK:([Frames].[UTC_time] >= 'Sep 16 2009 9:43PM' AND [Frames].[UTC_time] <= 'Sep 16 2009 11:43PM') ORDERED FORWARD)
|--Clustered Index Seek(OBJECT:([LEND_FLIGHT].[dbo].[Science_data].[PK_Science_data]), SEEK:([Science_data].[id]=[Frames].[id]) ORDERED FORWARD)
SELECT UTC_Time, SC2
FROM Frames
INNER LOOP JOIN Science_data
ON Frames.id = Science_data.id
WHERE UTC_time BETWEEN @curStart AND DATEADD(hour, 2, @curStart) AND GoodToMap = 1
Теперь по планам. Вы вероломно забили на индексы, и не сказали что они есть!
Так вот, глядя на планы видно что в первом случае используется ТОЛЬКО один индекс IX_UTC а во втором IX_UTC и IX_GoodToMap, а затем идет HASH джоин этих индексов.
Вот так должно быть:
SELECT UTC_Time, SC2
FROM Frames WITH (INDEX(IX_UTC))
INNER LOOP JOIN Science_data
ON Frames.id = Science_data.id
WHERE UTC_time BETWEEN @curStart AND DATEADD(hour, 2, @curStart) AND GoodToMap = 1
Здравствуйте, FilosOFF, Вы писали:
FOF>Спасибо, обычно, оценками показывается
Угу, увидел
FOF>Теперь по планам. Вы вероломно забили на индексы, и не сказали что они есть!
Это я как-то действительно дал... Но в любом случае — сейчас всё отлично выполняется, спасибо ещё раз (это в дополнение к оценкам ).