Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.012 c
2-1139947243
parovoZZ
2006-02-14 23:00
2006.03.05
Чем страшен Unsafe ... ?


2-1139990783
49 Cent
2006-02-15 11:06
2006.03.05
Можно ли через Dbgrid отображать подтаблицу?


15-1139161550
Джо
2006-02-05 20:45
2006.03.05
Ищу: Графоманский сайт


1-1138748103
FrykT
2006-02-01 01:55
2006.03.05
Временно отключить перерисовку скролла ListView


2-1140185829
Arxangel
2006-02-17 17:17
2006.03.05
Начало работы с FoxPro





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский