-
Дмитрий С © (14.03.15 17:31) [0]Добрый день.
Есть таблица услуг, у каждой услуги есть время начала и время окончания предоставления.
Пользователь задает диапазон дат и хочет получить список услуг, предоставляемые полностью или частично в этот диапазон дат.
Как организовать индекс для поиска? -
составной индекс по двум полям можно сделать
-
TohaNik © (14.03.15 18:30) [2]Нет такого индекса, нужно номер какой то, ФИО, ну или еще что то подобное..
Составной можно, но не та задача, ИМХО. -
where (eventEndDate >= UserStartDate) and (eventStartDate <= userEndDate)
-
ВладОшин © (14.03.15 21:21) [4]интересно.. именно индекс имхо никак
проверять на
if exists( selct 1 where UserStartDate between eventStartDate and eventEndDate)
set i := i +1
if exists( selct 1 where UserEndtDate between eventStartDate and eventEndDate)
set i := i +10
интерпретировать
select case
when i = 0 then 'мимо'
when i in (1,10) then case
when i = 1 then 'рана слева '
when i = 10 then 'рана справа '
утв
when i =11 then 'убил' -
ВладОшин © (14.03.15 21:21) [5]интересно.. именно индекс имхо никак
проверять на
if exists( selct 1 where UserStartDate between eventStartDate and eventEndDate)
set i := i +1
if exists( selct 1 where UserEndtDate between eventStartDate and eventEndDate)
set i := i +10
интерпретировать
select case
when i = 0 then 'мимо'
when i in (1,10) then case
when i = 1 then 'рана слева '
when i = 10 then 'рана справа '
утв
when i =11 then 'убил' -
TohaNik © (14.03.15 21:46) [6]
> составной индекс по двум полям можно сделать
или не правильно понял... или вообще не понял:(
по трем полям? -
Кщд © (14.03.15 22:33) [7]>TohaNik © (14.03.15 21:46) [6]
по двум
по этим: Ega23 © (14.03.15 19:29) [3]
>ВладОшин © (14.03.15 21:21) [4]
тяжёлая неделя выдалась?) -
Тащемта Влад жжот например. Нопалмом.
-
ВладОшин © (15.03.15 11:49) [9]да.. каюсь, был не трезв :)
-
Дмитрий С © (16.03.15 12:55) [10]
> Ega23 © (14.03.15 19:29) [3]
> ?
> 1
> where (eventEndDate >= UserStartDate) and (eventStartDate
> <= userEndDate)
Спасибо за подсказку!
Но даже в этом случае построить индекс не представляю как.
Похоже придется использовать какие-то трюки. -
Кщд © (16.03.15 12:59) [11]Дмитрий С © (16.03.15 12:55) [10]
>Но даже в этом случае построить индекс не представляю как.
вот так: eventStartDate, eventEndDate -
Дмитрий С © (16.03.15 13:42) [12]
> Кщд © (16.03.15 12:59) [11]
В этом случае, чем дальшебудет eventStartDate от userEndDate, тем менее эффективным будет индекс. Если eventStartDate = userStartDate - вообще бесполезным. -
Кщд © (16.03.15 14:07) [13]>Дмитрий С © (16.03.15 13:42) [12]
оба утверждения не соответствуют действительности -
Дмитрий С © (16.03.15 14:07) [14]
> Кщд © (16.03.15 14:07) [13]
Объясни. -
Кщд © (16.03.15 16:05) [15]>Дмитрий С © (16.03.15 14:07) [14]
- Рок-н-ролл мёртв из-за того, что Земля плоская в крапинку, т.к. хорёк
- Это не так
- Объясни?
))
Не знаю, о каких "индексах" говорили Вы, а наиболее распространённый в БД индекс - B*-tree (индекс на основе сбалансированного B-дерева).
Это ответ на все Ваши вопросы. -
Дмитрий С © (16.03.15 16:42) [16]
> Кщд © (16.03.15 16:05) [15]
При eventStartDate = userStartDate по первому измерению индекса (eventStartDate) выберет все элементы, поэтому подобный индекс будет неэффективным. -
Кщд © (16.03.15 17:07) [17]>Дмитрий С © (16.03.15 16:42) [16]
индекс становится неэффективным, когда по нему выбирается свыше 25-33% (в разных источниках - по-разному) записей от общего числа
если в Вашем случае (магия данных, ага) это так, то - неэффективен
рассуждения о каких-либо измерениях в случае с бинарным деревом - фтопку
за время существования ветки:
1. можно было прочесть базовую литературу (страшно, конечно, называть "литературой" эту пару страничек) по индексам;
2. можно было попробовать на практике (посмотреть план, снять тайминги и пр.).
ответ был дан ещё в "DVM © (14.03.15 17:32) [1]"
если он Вас не устраивает, это Ваше личное дело -
http://developerguru.net/post/date_range_intersection_condition/
какого то особого индекса не нужно, по времени начала и конца достаточно, условие отбора в ссылке (только not добавить, т.к. там на НЕ пересечение) -
Дмитрий С © (16.03.15 17:56) [19]
> sniknik © (16.03.15 17:23) [18]
> http://developerguru.net/post/date_range_intersection_condition/
>
> какого то особого индекса не нужно, по времени начала и
> конца достаточно, условие отбора в ссылке (только not добавить,
> т.к. там на НЕ пересечение)
Так вот Ega23 это и предложил в [3].where (eventEndDate >= UserStartDate) and (eventStartDate <= userEndDate)
Но как при этом работает индекс по двум полям (eventStartDate, eventEndDate)?
Расскажу как понимаю я, поправьте если что. Прошу не цепляться к словам.
Индекс по двум полям, это грубо говоря, индекс по конкатенации выровненных значений этих полей.
Иначе говоря индекс по двум полям строится следующим образом: Сначала строится индекс по первому полю, а затем, для каждой записи индекса строится индекс по второму полю. Аналогичным образом происходит поиск по индексу. Сначала ищется соответствие по первому полю индекса, а затем по второму для всех выбранных записей индекса.
Мы строим индекс по полям дат: (eventStartDate, eventEndDate).
Заполняем равномерно данными данными с 2000 по 2015 год.
А затем выбираем последние два месяца 2015 года:
where (eventEndDate >= '2015-11-01') and (eventStartDate <= '2015-12-31')
В этом случае СУБД начнет поиск по индексу следующим образом: Сначала выбирает по полю eventStartDate, затем из тех что выбралось выбирает по полю eventEndDate.
Но! Но по условию eventStartDate <= '2015-12-31' будут выбраны все данные, а по второму полю индекса субд будет сделать N выборок (N=количество записей 1 измерения индекса).