![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Составные индексы с "разной" сортировкой [Sybase ASA 9]
YuRock © (2007-03-20 13:44:00)Добрый день.
Вопрос такой: есть ли смысл использовать указание направления сортировки в узлах индексов, если они (направления) - разные? Как они работают, я пока-что не заметил. Вот пример:
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
Спасибо большое за любые ответы.
YuRock (2007-03-20 17:43:00) [1]я там давно сижу :)
Val (2007-03-20 16:42:00) [2]на скл.ру сходите, к специалистам по данному серверу.
YuRock (2007-03-20 16:39:00) [3]
> Jan (20.03.07 16:06) [18]
> вохзможно серверному оптимизатору виднее - когда ему индекс
> нужен а когда и нет...
Да эт. понятно, но мне то задачу решить (оптимизировать) надо, а как - я уже представить себе не могу... Ладно, спасибо всем.
Jan (2007-03-20 16:06:00) [4]вохзможно серверному оптимизатору виднее - когда ему индекс нужен а когда и нет...
YuRock (2007-03-20 15:40:00) [5]
> Val © (20.03.07 15:35) [16]
> скопом и пробуешь? может, по очереди?
Я как угодно уже пробовал. Все варианты.
Val (2007-03-20 15:35:00) [6]скопом и пробуешь? может, по очереди?
YuRock (2007-03-20 15:30:00) [7]есть индексы отдельно на LowLimit и HighLimit, есть на (LowLimit, HighLimit), есть на (Id,LowLimit). Уже на все, что можно.
Jan (2007-03-20 15:23:00) [8]
> Т.к. все-равно в среднем по половине таблицы сканом проходит.
> ..
индекс по каждому полю создал?
YuRock (2007-03-20 15:10:00) [9]> Jan
Но, к сожалению, толку, пока-что, естественно :) нет :(
Т.к. все-равно в среднем по половине таблицы сканом проходит...
YuRock (2007-03-20 14:41:00) [10]
> Jan (20.03.07 14:38) [10]
Спасибо за советы!
YuRock (2007-03-20 14:40:00) [11]
> select t1.* from DocLimits t1join DocLimits t2 on t1.id
> = t2.id and t2.LowLimit <= 1000000where t1.HighLimit >=
> 1000000
Хм. Отличная идея! Большое спасибо, буду думать...
Jan (2007-03-20 14:38:00) [12]
> 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:35:00) [13]
> Jan (20.03.07 14:33) [7]
Я так уже пробовал :)
Да, написать так можно. Но сервер будет использовать только один индекс (во вложенном запросе). Остальное - перебором, т.е. то же самое.
Jan (2007-03-20 14:35:00) [14]
> 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
Jan (2007-03-20 14:33:00) [15]
> 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
YuRock (2007-03-20 14:27:00) [16]
> 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
То оптимизатор сам выбирает правильный план для сортировки, зараза, а для фильтра - не хочет не то что выбирать, но и юзать то, во что его носом тыкают :(
Val (2007-03-20 14:20:00) [17]а что при двух отдельных индексах?
YuRock (2007-03-20 14:16:00) [18]В том то и дело, что НИЧЕГО. Я отчасти потому и вопрос задал, работает ли эта фича -указание для разных полей разное напровление сортировки.
Sergey13 (2007-03-20 14:12:00) [19]> [2] YuRock © (20.03.07 14:07)
А если, кстати сделать просто
CREATE INDEX i_DocLimits_LoHi ON DocLimits( LowLimit, HighLimit)
это что то поменяет?
YuRock (2007-03-20 14:07:00) [20]
> Почему не просто 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 :(
А должно быть моментально по моему разумению, коль уж в индексе поля сортировать возможно в разных направлениях...