Форум: "Базы";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];
ВнизОптимизация запроса Найти похожие ветки
← →
alsov © (2006-01-11 10:33) [0]Приветствую, Мастера
Помогите с оптимизацией запроса.
Есть табличка
CREATE TABLE [History] (
[DateTime] [datetime] NOT NULL ,
[Name] [varchar] (255) NOT NULL ,
[Value] [float] NULL ,
[test] [int] NULL)
GO
ALTER TABLE [History] ADD CONSTRAINT [PK_History] PRIMARY KEY CLUSTERED
(
[DateTime],
[Name]
) ON [PRIMARY]
GO
CREATE INDEX [IDX_rev] ON [History]([Name], [DateTime]) ON [PRIMARY]
GO
Нужно написать выборку всех последних значений для каждого Name.
Написал следующий селект, но работает очень долго (т.к. данных там прилично)
SELECT DateTime, Name, Value, Test
FROM History h1
WHERE (DateTime = (SELECT MAX(datetime) FROM History1 h2 WHERE h2.Name = h1.Name))
← →
Johnmen © (2006-01-11 10:40) [1]
SELECT Name, MAX(datetime)
FROM History h1
GROUP BY Name
← →
Johnmen © (2006-01-11 10:41) [2]кстати, для ускорения неплохо бы индекс на Name
← →
alsov © (2006-01-11 11:01) [3]мне еще поля Value и Теst в результате надо, а не только Name и datetime
← →
Johnmen © (2006-01-11 11:05) [4]Тогда только с подзапросом...
← →
evvcom © (2006-01-11 16:13) [5]Так попробуй:
SELECT
h1.DateTime, h1.Name, h1.Value, h1.Test
FROM History h1
INNER JOIN (
SELECT Name, MAX(datetime) as MaxDateTime
FROM History
GROUP BY Name
) h2
ON h2.Name = h1.Name AND
h2.MaxDateTime = h1.DateTime
← →
alsov © (2006-01-11 16:30) [6]Нет все равно долго.
Сделал ход конем. По специфике задачи можно выбирать данные за последнюю минуту. В результате получился вот такой запрос с полне приемлимой скоростью
begin
declare @todate datetime;
declare @fromdate datetime;
set @todate =getdate();
set @fromdate =dateadd(mi, -1, @todate);
SELECT DateTime, Name, Value, Test
FROM History h1
WHERE (DateTime = (SELECT MAX(datetime)
FROM History h2
WHERE (h2.name = h1.name)
and (datetime between @fromdate and @todate)))
end
← →
evvcom © (2006-01-11 16:37) [7]
> Нет все равно долго.
Во первых, у тебя выбрано [Name] [varchar] (255) в качестве ключа. Заведи нормальный ID с IDENTITY. Тогда в подзапросе будет GROUP BY ID и джойниться будет по нему же, что гораздо быстрее.
Во-вторых, можно поиграться с порядком полей в составном индексе, вплоть до включения в индекс всех полей, участвующих в запросе.
Возможно, для MSSQL что-то работает не так, как знаю я. Я сужу по Ораклу.
← →
alsov © (2006-01-11 18:46) [8]К сожалению структуру базы я менять не могу. Текстовый ключ мне тоже очень не нравиться
← →
Fay © (2006-01-11 20:50) [9]2 alsov © (11.01.06 16:30) [6]
> Нет все равно долго.
Долго - это сколько? У меня практически мгновенно.
← →
Fay © (2006-01-11 20:56) [10]2 evvcom © (11.01.06 16:37) [7]
> можно поиграться с порядком полей в составном индексе
Обратите внимание - там 2 индекса.
> вплоть до включения в индекс всех полей, участвующих в запросе
Это ничего не даст. Как и в Oracle.
← →
evvcom © (2006-01-12 08:24) [11]
> > можно поиграться с порядком полей в составном индексе
> Обратите внимание - там 2 индекса.
Это вот здесь
> CREATE INDEX [IDX_rev] ON [History]([Name], [DateTime])
> ON [PRIMARY]
> GO
2 индекса?
> > вплоть до включения в индекс всех полей, участвующих в
> запросе
> Это ничего не даст. Как и в Oracle.
Да что ты говоришь!
← →
Fay © (2006-01-12 09:13) [12]2 evvcom © (12.01.06 8:24) [11]
>Это вот здесь
>
> > CREATE INDEX [IDX_rev] ON [History]([Name],
>[DateTime])
>> ON [PRIMARY]
>> GO
>
> 2 индекса?
Нет, вот здесьALTER TABLE [History] ADD CONSTRAINT [PK_History]
PRIMARY KEY CLUSTERED
(
[DateTime],
[Name]
) ON [PRIMARY]
> Да что ты говоришь!
Проверил.
← →
evvcom © (2006-01-12 09:26) [13]
> Нет, вот здесь
А... Не обратил внимания, что первичный ключ тоже составной. Сорь.
> > Да что ты говоришь!
> Проверил.
Ну и?
← →
Fay © (2006-01-12 10:08) [14]2 evvcom © (12.01.06 9:26) [13]
> Ну и?
Никакой разницы.
← →
evvcom © (2006-01-12 10:16) [15]
> Никакой разницы.
1. На чем тестил? Если на MSSQL, то не знаю. На оракле разница есть, значит просто ты не понимаешь что на что влияет и не добился этой разницы.
2. Чем разницу смотрел?
← →
Fay © (2006-01-12 10:21) [16]2 evvcom © (12.01.06 10:16) [15]
Мне прекрасно известно, каким образом предполагалось добиться прироста скорости. Просто её (этой разницы) не видно.
Смотрел на 10g EE
← →
evvcom © (2006-01-12 10:30) [17]У меня 9i.
> Просто её (этой разницы) не видно.
"Не видно" и "нет разницы" - разные вещи. План-то меняется? Вероятно, у тебя мало тестовых данных, было б их миллион(ы), возможно, стало бы ее заметно на глаз. Ведь есть же разница, если сервер все данные возьмет из индекса или ему еще придется лезть в таблицу. На десятке записей этого действительно не заметишь.
← →
Fay © (2006-01-12 12:49) [18]2 evvcom © (12.01.06 10:30) [17]
> План-то меняется?
> Вероятно, у тебя мало тестовых данных
Согласен, всего 100`000 записей.
> На десятке записей этого действительно не заметишь.
"На десятке записей" план не изменится 8)
> Ведь есть же разница, если сервер все данные возьмет из индекса
Есть разница, но в (у меня) пределах погрешности. Надо было ещё при USE_NL посмотреть, но я уже снёс Oracle.
Признайся, ты сам проверял именно это запрос?
P.S.
EE - это Express
← →
Fay © (2006-01-12 13:14) [19]evvcom © (12.01.06 10:30) [17]
Проверил на миллионе - пофиг
← →
Fay © (2006-01-12 13:36) [20]О! Добился разницы в 11% ! Хоть что-то.
← →
evvcom © (2006-01-12 13:46) [21]
> Признайся, ты сам проверял именно это запрос?
Именно этот не проверял. У меня своих хватает. А кстати какой, 0 или 5?
> Проверил на миллионе - пофиг
Будет пофиг, если различных Name в этом миллионе мало. Сделай их 100"000 различных. Тогда или оптимизатор откажется вообще от индекса при отсутствии в индексе всех полей (кстати вообще-то по индексу была выборка?) или разница будет весьма заметной, так как после доступа к данным по индексу еще надо будет добраться в итоге и к данным в таблице.
> Надо было ещё при USE_NL посмотреть
Аналогично, если различных Name в этом миллионе очень мало.
Я сейчас как раз и занимаюсь оптимизацией старых своих запросов, писанных до курсов по оптимизации, когда понятий, как это делается внутри, еще не было совсем.
← →
evvcom © (2006-01-12 13:47) [22]
> О! Добился разницы в 11%
Ну дык.
> Сделай их 100"000 различных
и не то еще получишь
← →
evvcom © (2006-01-12 13:51) [23]
> > Сделай их 100"000 различных
>
> и не то еще получишь
особенно если начнешь сравнивать USE_NL + недостающие поля в индексе с USE_HASH + все нужные поля в индексе
← →
Fay © (2006-01-13 13:00) [24]2 evvcom © (12.01.06 13:51) [23]
При B(Name) = 400 и B(DateTime) = 300000 получил жуткие тормоза на длинном индексе. 8)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.017 c