Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
SQL 2000

select
 t1.id, t2.id, t3.id
from
 t1
left join
 t2
on t1.f1 =1 and t2.id = t1.f2
left join
 t3
on t1.f1 =2 and t3.id = t1.f2


не смотря на то, что t1.f1 со значением 1 не существует, в плане видны чтения таблицы и в статистике
Table 't2'. Scan count 125, logical reads 553, physical reads 9, read-ahead reads 24.
зачем он читает таблицу?
можно ли как-то этого избежать?

да, я понимаю, что такая структура БД не по феншую, но делал ее не я и реструктурировать возможности нет
4 фев 16, 09:53    [18771196]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
Glory
Member

Откуда:
Сообщений: 104760
TJ001
зачем он читает таблицу?

Потому что поля t1.f1 нет в t2
4 фев 16, 10:06    [18771245]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Glory,

конечно нет, ведь f1 - поле таблицы t1. в плане видно, что чтение производится сначала из t1 и для каждой строки выполняется поиск в t2. но я ведь задаю условие, которое в данном случае не выполняется, почему он сразу не выводит в результат null, а пытается что-то найти? где логика?

т.е. этого никак не избежать?
4 фев 16, 10:11    [18771262]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
Glory
Member

Откуда:
Сообщений: 104760
TJ001
но я ведь задаю условие, которое в данном случае не выполняется, почему он сразу не выводит в результат null, а пытается что-то найти? где логика?

Как же по-вашей логике можно сделать меньше чтений из таблицы, если нет условия, ограничивающего число чтений по этой таблице ?
Какое "условие не выполняется" для t2 ? t1.f1 =1 что ли ?

TJ001
в плане видно, что чтение производится сначала из t1 и для каждой строки выполняется поиск в t2

Вы решили пересказать план и вы так расскзывает про Nested Loops ?
4 фев 16, 10:15    [18771280]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
TJ001
почему он сразу не выводит в результат null
Куда?? Ведь такой строки в левой таблице нет.
4 фев 16, 10:18    [18771293]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Glory,

т.е. чтение из таблицы t2 можно ограничить только условием для значений в самой t2, так? но ведь даже для их проверки потребуется сделать хотя бы одно чтение из этой самой t2, правильно я понимаю?
4 фев 16, 10:22    [18771306]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
iap
TJ001
почему он сразу не выводит в результат null
Куда?? Ведь такой строки в левой таблице нет.
Какую-то чушь написал
Glory
Какое "условие не выполняется" для t2 ? t1.f1 =1 что ли ?
Не для t2, а для LEFT JOINа.
4 фев 16, 10:26    [18771312]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
Glory
Member

Откуда:
Сообщений: 104760
TJ001
но ведь даже для их проверки потребуется сделать хотя бы одно чтение из этой самой t2, правильно я понимаю?

Хосподи.
План строится БЕЗ всяких чтений.
На основе статистик/метаданных.
Ваш left join t2 on t1.f1 =1 and t2.id = t1.f2 говорит лишь о том, что надо для каждой записи t1 искать записи в t2
Как по статистике значений можно узнать, сколько записей t2 соответствует условию t1.f1 =1 ?

Сообщение было отредактировано: 4 фев 16, 10:29
4 фев 16, 10:26    [18771318]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Glory
TJ001
но ведь даже для их проверки потребуется сделать хотя бы одно чтение из этой самой t2, правильно я понимаю?

Хосподи.
План строится БЕЗ всяких чтений.
На основе статистик/метаданных.
Ваш left join t2 on t1.f1 =1 and t2.id = t1.f2 говорит лишь о том, что надо для каждой записи t1 искать записи в t2
Как по статистике значений можно узнать, сколько записей t2 соответствует условию t1.f1 =1 ?


никак
просто я думал что поиск записи выполняется только при выполнении всех условий...(((
выходит, что не уйти от этой проблемы? :'(
4 фев 16, 10:34    [18771356]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
Glory
Member

Откуда:
Сообщений: 104760
TJ001
просто я думал что поиск записи выполняется только при выполнении всех условий..

В смысле ?
А как узнать, соответствует ли запись всем условиям, не прочитав эту запись ?
Даже если отфильтровать сначала по t1.f1 =1, то все равно придется делать t2.id = t1.f2
И неизвестно, что дешевле сделать раньше

TJ001
выходит, что не уйти от этой проблемы? :'(

Вы хотите, чтобы вам по тексту запроса придумали идеальный план выполнения для неизвестной задачи с таблицами неизвестной структуры ?
4 фев 16, 10:40    [18771401]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
invm
Member

Откуда: Москва
Сообщений: 9396
TJ001
зачем он читает таблицу?
можно ли как-то этого избежать?
Потому что оптимизатор выбрал такой способ соединения таблиц (наверное там hash join). А при Nested Loops возможно было бы делать фильтрацию перед чтением из t2.
use tempdb;
go

create table dbo.t1 (id int primary key, v int, f int);
create table dbo.t2 (id int primary key, v int);
go

insert into dbo.t1 values (1, 1, 2);
insert into dbo.t2 values (1, 1);
go

set statistics profile, io on;
go

select
 t1.v, t2.v
from
 dbo.t1 left hash join
 dbo.t2 on t1.f = 1 and t2.id = t1.id;

select
 t1.v, t2.v
from
 dbo.t1 left loop join
 dbo.t2 on t1.f = 1 and t2.id = t1.id;
go

set statistics profile, io off;
go

drop table dbo.t1, dbo.t2;
go

Не помню, будет ли так работать на 2000-м.
4 фев 16, 10:49    [18771452]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Glory
В смысле ?
А как узнать, соответствует ли запись всем условиям, не прочитав эту запись ?
Даже если отфильтровать сначала по t1.f1 =1, то все равно придется делать t2.id = t1.f2
И неизвестно, что дешевле сделать раньше

если взять ЯП, то там часто в условиях "если (а=1) и (б=2) то"
"б" даже не проверяется, если а <> 1
здесь я тоже надеялся на такой исход, но он не прокатывает
отсюда я понимаю, что увидев join, сервер уже решил для себя, что будет читать присоединяемую таблицу в любом случае, независимо от условий этого самого джойна

наверно, моя проблема в непрочтении толстой книги(книг) по sql, но именно по этой причине я пришел сюда, в надежде узнать причину вопроса, но обтекаю уже полчаса, так толком и не узнав ничего

Glory
Вы хотите, чтобы вам по тексту запроса придумали идеальный план выполнения для неизвестной задачи с таблицами неизвестной структуры ?

нет, я вовсе этого не просил

меня бы устроили некие наиболее часто применяемые в таких случаях методы, если они существуют
хотя бы один пример для сферической таблицы в вакууме, чтобы было видно принцип
4 фев 16, 10:51    [18771467]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
Glory
Member

Откуда:
Сообщений: 104760
TJ001
если взять ЯП, то там часто в условиях "если (а=1) и (б=2) то"
"б" даже не проверяется, если а <> 1

Только вы почему оперируете скалярными выражениями. А не наборами данных. И не в поиске самого дешевого плана
Ваш посыл соответствует left join t2 on t1.f1 =1 and t2.id = 2

TJ001
нет, я вовсе этого не просил

меня бы устроили некие наиболее часто применяемые в таких случаях методы, если они существуют
хотя бы один пример для сферической таблицы в вакууме, чтобы было видно принцип

Если вы уже в голове составили свой план, то читайте в хелпе про хинты(hints)

Сообщение было отредактировано: 4 фев 16, 10:56
4 фев 16, 10:55    [18771493]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
invm,

в моем случае, без хинтов, оптимизатор по умолчанию выбирает Nested Loops
но ваш пример имеет такой же план, как и мой
если поменять условие в вашем запросе на t1.f = 0, то
Clustered Index Seek: количество выполнений - 1, факт кол строк - 0
я наивно мечтал физические чтения в этом случае свести к нулю, но нет, так не получится, как я понимаю...
4 фев 16, 11:05    [18771544]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
invm
Member

Откуда: Москва
Сообщений: 9396
TJ001
в моем случае, без хинтов, оптимизатор по умолчанию выбирает Nested Loops
Значит в 2000-м оптимизатор еще не научили такой фильтрации.

Сообщение было отредактировано: 4 фев 16, 11:08
4 фев 16, 11:06    [18771553]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
Glory
Member

Откуда:
Сообщений: 104760
select t1.id, t2.id, NULL
from t1 inner join t2 on t2.id = t1.f2
where t1.f1 =1 
union 
select t1.id, NULL, t3.id
from t1 inner join  t3 on t3.id = t1.f2
where t1.f1 =2
4 фев 16, 11:09    [18771569]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Glory
Только вы почему оперируете скалярными выражениями. А не наборами данных. И не в поиске самого дешевого плана
Ваш посыл соответствует left join t2 on t1.f1 =1 and t2.id = 2

да, теперь я понимаю разницу, но у меня нет другого выбора, значение в поле f1 - это единственный признак того, в какой таблице нужно искать запись с ключом из поля f2
поэтому я и пытался сделать что-то типа динамического соединения, но оно не работает так, как я хотел бы
о том как динамические джойны спрашивали много раз и везде есть ответы, но это, как выяснилось, не избавляет от лишних чтений
4 фев 16, 11:10    [18771573]     Ответить | Цитировать Сообщить модератору
 Re: Почему left join выполняет чтение таблицы, при невыполнимом условии?  [new]
TJ001
Member

Откуда: от верблюда
Сообщений: 408
Glory
select t1.id, t2.id, NULL
from t1 inner join t2 on t2.id = t1.f2
where t1.f1 =1 
union 
select t1.id, NULL, t3.id
from t1 inner join  t3 on t3.id = t1.f2
where t1.f1 =2


похоже, это то что нужно! спасибо! :))
4 фев 16, 11:13    [18771594]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить