Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.06.10;
Скачать: CL | DM;

Вниз

Составные индексы с "разной" сортировкой   Найти похожие ветки 

 
YuRock ©   (2007-03-20 13:44) [0]

Добрый день.

Вопрос такой: есть ли смысл использовать указание направления сортировки в узлах индексов, если они (направления) - разные? Как они работают, я пока-что не заметил. Вот пример:

CREATE INDEX i_DocLimits_LoHi ON DocLimits( LowLimit ASC, HighLimit DESC )
оба поля - unsigned int

Так вот, использовать такую сортировку не получается. Запрос типа
select * from DocLimits where LowLimit <= 1000000 AND HighLimit >= 1000000
Не работает по индексу. ( Если вручную указать план - то индекс использоваться будет, но отбираться по нему будет только "половина" таблицы, а по второму полю (HighLimit) будет sequentially.

Никто не сталкивался с подобной проблемой? Если эта фича не работает - посоветуете что-нибудь другое для решения этой проблемы?

Сервер ASA 9.0.2
В таблице - 16 миллионов записей. Результаты запросов, как в примере - 2-4 записи. Данные в полях LowLimit и HighLimit не уникальные, но и сильно не повторяющиеся.

min/мах значение этих полей:
select
 ( select min(LowLimit) from doclimits ) as minlo,
 ( select max(LowLimit) from doclimits ) as maxlo,
 ( select min(HighLimit) from doclimits ) as minhi,
 ( select max(HighLimit) from doclimits ) as maxhi
from dummy

minlo,maxlo,minhi,maxhi
1048577,231735297,1048577,231740120

SELECT AVG(HighLimit) FROM DocLimits

46283869

Спасибо большое за любые ответы.


 
Sergey13 ©   (2007-03-20 13:58) [1]

> Так вот, использовать такую сортировку не получается. Запрос типа
> select * from DocLimits where LowLimit <= 1000000 AND HighLimit >= 1000000
> Не работает по индексу.
И не получится наверное. Ибо в условии не четкое равенство. Другими словами записей, удовлетворяющих условию, может быть и миллион и два и больше. Индекс при этом будет только мешать из-за дополнительного чтения. Поэтому оптимизатор видимо (справедливо) посчитал, что фул скан будет производительнее.

> select
> ( select min(LowLimit) from doclimits ) as minlo,
> ( select max(LowLimit) from doclimits ) as maxlo,
> ( select min(HighLimit) from doclimits ) as minhi,
> ( select max(HighLimit) from doclimits ) as maxhi
> from dummy

Почему не просто
select min(LowLimit),max(LowLimit),min(HighLimit),max(HighLimit) from doclimits

? Все выберется за один проход вместо 4-х.

ЗЫ: Все исключительно ИМХО, с указанным сервером не встречался


 
YuRock ©   (2007-03-20 14:07) [2]


> Почему не просто select min(LowLimit),max(LowLimit),min(HighLimit),
> max(HighLimit) from doclimits

Да, так проще :) Но медленнее. В моем варианте отрабатывает моментально каждый подзапрос по индексу, а тут - полный перебор будет идти. Но это не столь важно. Это так, вспомогательные данные. мож кому поможет дать дельный совет :)


> И не получится наверное. Ибо в условии не четкое равенство.
>  Другими словами записей, удовлетворяющих условию, может
> быть и миллион и два и больше. Индекс при этом будет только
> мешать из-за дополнительного чтения. Поэтому оптимизатор
> видимо (справедливо) посчитал, что фул скан будет производительнее.
>


Может, и справедливо, но неправильно в моем случае. В результате такого запроса у меня ВСЕГДА получается от 0 до 10-15 записей из 16 миллионов.

Но дело даже не в оптимизаторе. Когда я пишу

select * from DocLimits WITH( INDEX( i_DocLimits_LoHi ) ) where LowLimit <= 1000000 AND HighLimit >= 1000000

ничего в лучшую сторону почти не меняется. Т.е. запрос в среднем в 2 раза быстрее начинает работать. Ну, не 4 минуты, а 2 :(
А должно быть моментально по моему разумению, коль уж в индексе поля сортировать возможно в разных направлениях...


 
Sergey13 ©   (2007-03-20 14:12) [3]

> [2] YuRock ©   (20.03.07 14:07)

А если, кстати сделать просто
CREATE INDEX i_DocLimits_LoHi ON DocLimits( LowLimit, HighLimit)
это что то поменяет?


 
YuRock ©   (2007-03-20 14:16) [4]

В том то и дело, что НИЧЕГО. Я отчасти потому и вопрос задал, работает ли эта фича -указание для разных полей разное напровление сортировки.


 
Val ©   (2007-03-20 14:20) [5]

а что при двух отдельных индексах?


 
YuRock ©   (2007-03-20 14:27) [6]


> Val ©   (20.03.07 14:20) [5]
> а что при двух отдельных индексах?


То же, что и


> Когда я пишуselect * from DocLimits WITH( INDEX( i_DocLimits_LoHi
> ) ) where LowLimit <= 1000000 AND HighLimit >= 1000000ничего
> в лучшую сторону почти не меняется. Т.е. запрос в среднем
> в 2 раза быстрее начинает работать. Ну, не 4 минуты, а 2
> :(


Кстати, такая особенность: если я пишу такое:

SELECT *
FROM DocLimits
ORDER BY LowLimit ASC, HighLimit DESC

То оптимизатор сам выбирает правильный план для сортировки, зараза, а для фильтра - не хочет не то что выбирать, но и юзать то, во что его носом тыкают :(


 
Jan   (2007-03-20 14:33) [7]


> CREATE INDEX i_DocLimits_LoHi ON DocLimits( LowLimit ASC,
>  HighLimit DESC )

а если два индекса?

CREATE INDEX i_DocLimits_Lo ON DocLimits( LowLimit ASC)
CREATE INDEX i_DocLimits_LoHi ON DocLimits( HighLimit DESC )

в Сервере ASA 9.0.2 можно так написать?

select * from (
select * from DocLimits
where LowLimit <= 1000000) t
where HighLimit >= 1000000


 
Jan   (2007-03-20 14:35) [8]


> select * from (
> select * from DocLimits
> where LowLimit <= 1000000) t
> where HighLimit >= 1000000

или так:

select t1.* from  DocLimits t1
join DocLimits t2 on t1.id = t2.id and  t2.LowLimit <= 1000000
where t1.HighLimit >= 1000000


 
YuRock ©   (2007-03-20 14:35) [9]


> Jan   (20.03.07 14:33) [7]


Я так уже пробовал :)

Да, написать так можно. Но сервер будет использовать только один индекс (во вложенном запросе). Остальное - перебором, т.е. то же самое.


 
Jan   (2007-03-20 14:38) [10]


> select t1.* from  DocLimits t1
> join DocLimits t2 on t1.id = t2.id and  t2.LowLimit <= 1000000
> where t1.HighLimit >= 1000000

или так:

select t1.* from  DocLimits t1
where t1.HighLimit >= 1000000
and exists(select * from DocLimits t2
where t1.id = t2.id and  t2.LowLimit <= 1000000)


 
YuRock ©   (2007-03-20 14:40) [11]


> select t1.* from  DocLimits t1join DocLimits t2 on t1.id
> = t2.id and  t2.LowLimit <= 1000000where t1.HighLimit >=
> 1000000


Хм. Отличная идея! Большое спасибо, буду думать...


 
YuRock ©   (2007-03-20 14:41) [12]


> Jan   (20.03.07 14:38) [10]

Спасибо за советы!


 
YuRock ©   (2007-03-20 15:10) [13]

> Jan

Но, к сожалению, толку, пока-что, естественно :) нет :(

Т.к. все-равно в среднем по половине таблицы сканом проходит...


 
Jan   (2007-03-20 15:23) [14]


> Т.к. все-равно в среднем по половине таблицы сканом проходит.
> ..

индекс по каждому полю создал?


 
YuRock ©   (2007-03-20 15:30) [15]

есть индексы отдельно на LowLimit и HighLimit, есть на (LowLimit, HighLimit), есть на (Id,LowLimit). Уже на все, что можно.


 
Val ©   (2007-03-20 15:35) [16]

скопом и пробуешь? может, по очереди?


 
YuRock ©   (2007-03-20 15:40) [17]


> Val ©   (20.03.07 15:35) [16]
> скопом и пробуешь? может, по очереди?

Я как угодно уже пробовал. Все варианты.


 
Jan   (2007-03-20 16:06) [18]

вохзможно серверному оптимизатору виднее - когда ему индекс нужен а когда и нет...


 
YuRock ©   (2007-03-20 16:39) [19]


> Jan   (20.03.07 16:06) [18]
> вохзможно серверному оптимизатору виднее - когда ему индекс
> нужен а когда и нет...

Да эт. понятно, но мне то задачу решить (оптимизировать) надо, а как - я уже представить себе не могу... Ладно, спасибо всем.


 
Val ©   (2007-03-20 16:42) [20]

на скл.ру сходите, к специалистам по данному серверу.


 
YuRock ©   (2007-03-20 17:43) [21]

я там давно сижу :)



Страницы: 1 вся ветка

Текущий архив: 2007.06.10;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.021 c
2-1179309426
allucard
2007-05-16 13:57
2007.06.10
Пример на языке С создание окна, помогите перевести строку


2-1179483933
News
2007-05-18 14:25
2007.06.10
Сетевое приложение


11-1161750263
Lari
2006-10-25 08:24
2007.06.10
Ошибка чтения файла при использовании PStream


2-1179517412
Konfetka
2007-05-18 23:43
2007.06.10
Дата


15-1179219626
Rule
2007-05-15 13:00
2007.06.10
Открыл для себя новую альтернативу жабы