Допустим есть таблица три поля которой в кластерном инденксе (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=''?
Индекс не может изменять семантику запроса, это инструмент оптимизации, а оптимизация предполагает неизменный результат. Ты предлагаешь фичу, которая бы выдавала другую выборку. Ну или я вообще не понял, что ты хочешь. Конечно такое невозможно. Ну возьмёт от этот индекс с b = ''. Но в результаты первого запроса попадают и те строки, у которых b <> ''. Как их прикажете находить?
Re[2]: Значение по умолчанию для колонки в индексе?
Здравствуйте, vsb, Вы писали:
vsb>Ты предлагаешь фичу, которая бы выдавала другую выборку. Ну или я вообще не понял, что ты хочешь. Конечно такое невозможно. Ну возьмёт от этот индекс с b = ''. Но в результаты первого запроса попадают и те строки, у которых b <> ''. Как их прикажете находить?
Да вот мне то как раз не нужно b <> ''. Запросы к этой таблице будут (всегда) двух вариантов либо where a='val..' and b='val..' and c='val..', либо a='val..' and b='' and c='val..'. Вот и подумалось нет ли чего такого в скуле, фоново дополняющего отсутствующее значение из индекса, чтобы не писать b='' когда указаны a и c. Ну нет так нет.
Здравствуйте, 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
Здравствуйте, rFLY, Вы писали:
FLY>Добрый день
FLY>Допустим есть таблица три поля которой в кластерном инденксе (a, b и c, все NOT NULL). Поле b может иметь какое либо значение или пусто ''. Есть ли возможность для него указать какую-то константу, когда при выборке в условии выборки используются a и c?
FLY>Можно как-то такое провернуть или всегда придется писать AND t.b=''?
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Re[2]: Значение по умолчанию для колонки в индексе?
Здравствуйте, vmpire, Вы писали:
V>Из вопроса не совсем понятно, что должно искаться, если в условии b не указан, а указаны только a и c: b должен игнорироваться в поиске или неявно заменяться на b=''?
b='' V>- Если при этом должны искаться только пустые b, то нужно это указать явно, а то как сервер до этого догадается?
Я себе это представляю так: сервер для подходящего индекса видит что заданы значения для первых и конечных полей, но отсутствует середина и чтобы целиком считать по индексу, а не все записи подходящие под первые поля, а затем отфильтровать по конечным, он для пропущенных полей использует заданные константы. Но это конечно так, фантазии.
Re[3]: Значение по умолчанию для колонки в индексе?
Здравствуйте, 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]: Значение по умолчанию для колонки в индексе?
Здравствуйте, 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]: Значение по умолчанию для колонки в индексе?
Здравствуйте, rFLY, Вы писали:
FLY>Это не один раз написать. Эта таблица что-то вроде хранилища однотипных справочников, где колонка a — это ид справочника, колонка b — подгруппа, а c — ид элемента внтури a и b.
Если условия на a и c всегда присутствуют в запросе, то можно перестроить индекс, указав поля в порядке (a, c, b) и получить желаемое.
НО! Для получения записи "справочника" по PK нужно всегда указывать все ключевые поля. Иначе можно получить более одной записи.
Re[6]: Значение по умолчанию для колонки в индексе?
Здравствуйте, wildwind, Вы писали:
W>Если условия на a и c всегда присутствуют в запросе, то можно перестроить индекс, указав поля в порядке (a, c, b) и получить желаемое.
В таком случае при джойне, но уже когда задано b, выйдет ровно таже самое: a будет в seek predicated, b в просто predicate. Лучше уж оставить в том порядке и всегда указывать b.
W>НО! Для получения записи "справочника" по PK нужно всегда указывать все ключевые поля. Иначе можно получить более одной записи.
Да это понятно
Здравствуйте, 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') случится чудо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.