Значение по умолчанию для колонки в индексе?
От: rFLY  
Дата: 16.04.19 13:12
Оценка:
Добрый день

Допустим есть таблица три поля которой в кластерном инденксе (a, b и c, все NOT NULL). Поле b может иметь какое либо значение или пусто ''. Есть ли возможность для него указать какую-то константу, когда при выборке в условии выборки используются a и c?
Т.е. сейчас, когда предыдущая колонка из индекса опущена, то в seek predicate попадают все условия до этой колонки, а все оставшееся в просто predicate:
SELECT t.* FROM t WHERE t.a='val1' AND t.c='val3'
Predicate
t.c = 'val3'
Seek Predicates
t.a = 'val1'


А хотелось бы, чтобы при таком запросе было:
Seek Predicates
t.a = 'val1'
t.b = ''
t.c = 'val3'

как если бы запрос был таким:
SELECT t.* FROM t WHERE t.a='val1' AND t.b='' AND t.c='val3'


Можно как-то такое провернуть или всегда придется писать AND t.b=''?
Re: Значение по умолчанию для колонки в индексе?
От: vsb Казахстан  
Дата: 16.04.19 13:33
Оценка: +1
Индекс не может изменять семантику запроса, это инструмент оптимизации, а оптимизация предполагает неизменный результат. Ты предлагаешь фичу, которая бы выдавала другую выборку. Ну или я вообще не понял, что ты хочешь. Конечно такое невозможно. Ну возьмёт от этот индекс с b = ''. Но в результаты первого запроса попадают и те строки, у которых b <> ''. Как их прикажете находить?
Re[2]: Значение по умолчанию для колонки в индексе?
От: rFLY  
Дата: 16.04.19 13:53
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Ты предлагаешь фичу, которая бы выдавала другую выборку. Ну или я вообще не понял, что ты хочешь. Конечно такое невозможно. Ну возьмёт от этот индекс с b = ''. Но в результаты первого запроса попадают и те строки, у которых b <> ''. Как их прикажете находить?

Да вот мне то как раз не нужно b <> ''. Запросы к этой таблице будут (всегда) двух вариантов либо where a='val..' and b='val..' and c='val..', либо a='val..' and b='' and c='val..'. Вот и подумалось нет ли чего такого в скуле, фоново дополняющего отсутствующее значение из индекса, чтобы не писать b='' когда указаны a и c. Ну нет так нет.
Re: Значение по умолчанию для колонки в индексе?
От: vmpire Россия  
Дата: 16.04.19 14:19
Оценка:
Здравствуйте, rFLY, Вы писали:

FLY>Добрый день


FLY>Допустим есть таблица три поля которой в кластерном инденксе (a, b и c, все NOT NULL). Поле b может иметь какое либо значение или пусто ''. Есть ли возможность для него указать какую-то константу, когда при выборке в условии выборки используются a и c?

FLY>Т.е. сейчас, когда предыдущая колонка из индекса опущена, то в seek predicate попадают все условия до этой колонки, а все оставшееся в просто predicate:
FLY>Можно как-то такое провернуть или всегда придется писать AND t.b=''?
Правильнее всего явно писать t.b=''
Из вопроса не совсем понятно, что должно искаться, если в условии b не указан, а указаны только a и c: b должен игнорироваться в поиске или неявно заменяться на b=''?
— Если при этом должны искаться только пустые b, то нужно это указать явно, а то как сервер до этого догадается?
— Если должны искаться любые b, а хочется просто оптимизировать запрос для такого варианта, то можно сделать дополнительный некластерный индекс только по a и c
Re: Значение по умолчанию для колонки в индексе?
От: biochemist СССР https://www.anekdot.ru/i/caricatures/normal/20/7/27/1595846503.jpg
Дата: 16.04.19 14:38
Оценка:
Здравствуйте, rFLY, Вы писали:

FLY>Добрый день


FLY>Допустим есть таблица три поля которой в кластерном инденксе (a, b и c, все NOT NULL). Поле b может иметь какое либо значение или пусто ''. Есть ли возможность для него указать какую-то константу, когда при выборке в условии выборки используются a и c?


FLY>Можно как-то такое провернуть или всегда придется писать AND t.b=''?

«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Re[2]: Значение по умолчанию для колонки в индексе?
От: rFLY  
Дата: 16.04.19 14:39
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Из вопроса не совсем понятно, что должно искаться, если в условии b не указан, а указаны только a и c: b должен игнорироваться в поиске или неявно заменяться на b=''?

b=''
V>- Если при этом должны искаться только пустые b, то нужно это указать явно, а то как сервер до этого догадается?
Я себе это представляю так: сервер для подходящего индекса видит что заданы значения для первых и конечных полей, но отсутствует середина и чтобы целиком считать по индексу, а не все записи подходящие под первые поля, а затем отфильтровать по конечным, он для пропущенных полей использует заданные константы. Но это конечно так, фантазии.
Re[3]: Значение по умолчанию для колонки в индексе?
От: wildwind Россия  
Дата: 16.04.19 15:42
Оценка: +1
Здравствуйте, rFLY, Вы писали:

FLY>Да вот мне то как раз не нужно b <> ''. Запросы к этой таблице будут (всегда) двух вариантов либо where a='val..' and b='val..' and c='val..', либо a='val..' and b='' and c='val..'. Вот и подумалось нет ли чего такого в скуле, фоново дополняющего отсутствующее значение из индекса, чтобы не писать b='' когда указаны a и c. Ну нет так нет.


То есть вся эта канитель из-за того, чтобы не писать b=''???
Не понимаю, как можно этого хотеть, когда можно обойтись одним вариантом запроса, не размножать код, не плодить ошибки и тесткейсы и т.д.?
Re[4]: Значение по умолчанию для колонки в индексе?
От: rFLY  
Дата: 16.04.19 15:59
Оценка:
Здравствуйте, wildwind, Вы писали:

W>То есть вся эта канитель из-за того, чтобы не писать b=''???

Почему же канитель, стало интересно и решил спросить.

W>Не понимаю, как можно этого хотеть, когда можно обойтись одним вариантом запроса, не размножать код, не плодить ошибки и тесткейсы и т.д.?

Это не один раз написать. Эта таблица что-то вроде хранилища однотипных справочников, где колонка a — это ид справочника, колонка b — подгруппа, а c — ид элемента внтури a и b.
Как-то так (забегая на перед, для одного a b не может быть и пусто и иметь какое-то значение):
a    b    c    d...
Сп1  Гр1  01
Сп1  Гр1  02
Сп1  Гр2  01
Сп1  Гр2  02
Сп2       01
Сп2       02
...
СпN  ГрN  01
СпN  ГрN  02
Re[5]: Значение по умолчанию для колонки в индексе?
От: wildwind Россия  
Дата: 16.04.19 16:23
Оценка: +1
Здравствуйте, rFLY, Вы писали:

FLY>Это не один раз написать. Эта таблица что-то вроде хранилища однотипных справочников, где колонка a — это ид справочника, колонка b — подгруппа, а c — ид элемента внтури a и b.


Если условия на a и c всегда присутствуют в запросе, то можно перестроить индекс, указав поля в порядке (a, c, b) и получить желаемое.
НО! Для получения записи "справочника" по PK нужно всегда указывать все ключевые поля. Иначе можно получить более одной записи.
Re[6]: Значение по умолчанию для колонки в индексе?
От: rFLY  
Дата: 16.04.19 17:07
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Если условия на a и c всегда присутствуют в запросе, то можно перестроить индекс, указав поля в порядке (a, c, b) и получить желаемое.

В таком случае при джойне, но уже когда задано b, выйдет ровно таже самое: a будет в seek predicated, b в просто predicate. Лучше уж оставить в том порядке и всегда указывать b.

W>НО! Для получения записи "справочника" по PK нужно всегда указывать все ключевые поля. Иначе можно получить более одной записи.

Да это понятно
Re: Значение по умолчанию для колонки в индексе?
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.05.19 17:50
Оценка:
Здравствуйте, rFLY, Вы писали:

FLY>Добрый день


FLY>Допустим есть таблица три поля которой в кластерном инденксе (a, b и c, все NOT NULL). Поле b может иметь какое либо значение или пусто ''. Есть ли возможность для него указать какую-то константу, когда при выборке в условии выборки используются a и c?

FLY>Т.е. сейчас, когда предыдущая колонка из индекса опущена, то в seek predicate попадают все условия до этой колонки, а все оставшееся в просто predicate:
FLY>
FLY>SELECT t.* FROM t WHERE t.a='val1' AND t.c='val3'
FLY>Predicate
FLY>t.c = 'val3'
FLY>Seek Predicates
FLY>t.a = 'val1'
FLY>


FLY>А хотелось бы, чтобы при таком запросе было:

FLY>
FLY>Seek Predicates
FLY>t.a = 'val1'
FLY>t.b = ''
FLY>t.c = 'val3'

FLY>как если бы запрос был таким:
FLY>SELECT t.* FROM t WHERE t.a='val1' AND t.b='' AND t.c='val3'
FLY>


FLY>Можно как-то такое провернуть или всегда придется писать AND t.b=''?

можно написать TVF c дефолтным параметром.
CREATE FUNCTION search_t (
    @a varchar(max),
    @c varchar(max),
    @b varchar(max) = ''
)
RETURNS TABLE
AS
RETURN
    SELECT t.* FROM t WHERE t.a=@a AND t.b = @b AND t.c=@c


Тогда при вызове search_t('val1', 'val3') случится чудо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.