Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » InterBase и FireBird: вопросы по работе и их решение

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

Открыть новую тему     Написать ответ в эту тему

ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
а вы посмотрите на план выполнения запроса - сразу станет видно
 
потому что join - это всё равно что написать Select ... from t1,t2,... where...  
и он перебирает всё подряд из всех возможных комбинаций t1*t2*....  
а вот left join перебирает "поумнее"

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 22:39 24-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004
Спасибо за мнение. У меня план запроса не меняется. Я не знаю тех условий когда он меняется, план запроса до буквы - тот же. Разницы в left join и join нет никакой, только в одном случае результат сравнения я пихаю в добавление записи выборки, в другом случае не пихаю. То есть join обязан быть быстрее.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 13:09 25-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Существует более правдоподобная версия. Дело в том, что пока я пишу LEFT, в это время сервер уже готовит записи. Ещё есть версии?

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 17:46 25-12-2013
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
не видя конкретных таблиц, данных, запросов и их планов (а тем более угадывать что там с ними делается в одном или другом случае) рассуждать тяжело. по теории запрос с join (where) и должен обрабатываться дольше чем с left join, но ведь и оптимизаторы запросов сейчас не те, что раньше были, могут неплохо ускорять

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 01:34 26-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004

Цитата:
не видя конкретных таблиц

Тут нет конкретики и не надо.
 
Дело в том, что когда имеем простой JOIN, есть вероятность, что в результирующей выборке будет ноль записей, следовательно результат строится динамически. Предположим у нас в результате возвращается 10 тысяч записей. Это значит, что под результат я буду 10 тысяч раз перераспределять память. Перераспределение это выделение памяти на одну запись больше, копирование памяти из старого куска, освобождение памяти старого куска. В случае с LEFT JOIN не существует смысла так поступать. Я заранее подготовлю кусок побольше и буду его заполнять без лишних телодвижений. То есть вместо 10 тысяч раз я обращусь к менеджеру памяти один раз. Конечно есть вероятность что сервер не пользуется земными технологиями, но я в это не верю. В любом случае я отдаю какие-то байты и эти байты где-то в памяти лежат. Если Вы независимо протестируете то увидите именно те миллисекунды, которые мы имеем в разнице между LEFT и простым JOIN.
 
Всем удачного Нового Года.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 07:24 26-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004

Цитата:
запрос с join (where)

Ой, точно. Это хорошо, что Вы упомянули WHERE. Казалось бы наличие условия должно нам сказать что конечное количество записей не известно. Оказалось не так. Я нашёл свой конкретный запрос и там был WHERE. Видимо действительно инопланетные технологи. Дело в том, что если Вы возьмёте ассемблер, вернётесь в начало девяностых годов, поработаете с таблицей в которой указаны ассемблерные тики (количество тиков процессора), то Вам просто будет очевидно, что иногда лучше предварительно посчитать байты, а потом выделить блок памяти. Я точно подозреваю, что FireBird именно так и делает. Вероятно наличие индексов тоже влияет. Но не суть, суть в том что WHERE ещё ничего нам не говорит.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 10:55 26-12-2013 | Исправлено: delover, 10:57 26-12-2013
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
под where я имел в виду вот что -  
select ... from t1 join t2 on (условие) равносильно select ... from t1,t2 where (условие)
т.е. строятся все возможные комбинации из т1*т2 и проверяются на (условие)
а в случае select ... from t1 left join t2 on (условие) - идёт "склейка" по условию, что проще
а что касается использования индексов - так это уже внутреннее дело БД, особенно оптимизатора. и тут имеет значение в каком порядке, есть ли индексы, есть ли full scan итд. и оптимизатору firebird до оптимизатора oracle, например - расти и расти еще...

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 15:54 26-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004
Вы как в воду глядели. Я поторопился со where, where быть не должно по условию задачи. Когда я первый раз задал вопрос, мне начали отвечать что идут сравнения с null и об этом пишут все в интернете. Думаю задачка прикольная сама по себе. Будете прикалываться над коллегами - не забудьте про ассемблерные тики. Но время набегающих миллисекунд - именно то, что является издержками перераспределений.
 

Цитата:
и тут имеет значение в каком порядке, есть ли индексы

Нет индексов. По условию задачи джойны идут однотипно через форейн к примари.
 

Цитата:
все возможные комбинации из т1*т2  

Ещё раз. В моём примере у join и left join абсолютно одинаковая математическая нагрузка - результирующая выборка одна и та же. Количество комбинаций одно и то же. Просто любое дополнительное условие отменит Count, что заставляет строить результат динамически. Отсутствие left это и есть дополнительное условие.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 18:06 26-12-2013
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover

Цитата:
Нет индексов. По условию задачи джойны идут однотипно через форейн к примари.  

ну как же нет индексов? по праймари и по форейну индексы и берутся.  

Цитата:
Количество комбинаций одно и то же

это результат один и тот же, а вот количество комбинаций, которые просматриваются для получения результата - разные (хотя опять же, умный оптимайзер может догадаться)
 
кроме того, может играть роль prepared у запросов (если у них действительно один и тот же план получается) - попробуйте их наоборот запускать - вдруг теперь и время поменяется соответственно, т.е. первый тормозит (т.к. его нужно еще prepare) а второй уже на всём готовеньком

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 20:28 26-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
ну как же нет индексов? по праймари и по форейну индексы и берутся.

Вы имеете ввиду, что если я переименую PK_ то оптимизатор это не заметит? Я бы завязал на PK, зато картинка в плане красивая. Но это надо тестить ещё.
 

Цитата:
кроме того, может играть роль prepared у запросов

На эту шляпу я тестил, миллисекунды не то что предсказуемые, они для меня огромные. Все прозаичнее, есть и дисковая память и "Capacity" и даже препаред. Подозреваю, что даже есть разница в простом запросе и запросе который мы засунули в сохранёнку. Но эту разницу Вы увидите даже при отсутствии индексов кеев и прошитом пустом плане запроса.
 

Цитата:
это результат один и тот же, а вот количество комбинаций, которые просматриваются для получения результата - разные

Я так и думал что Вы немного не понимаете. Вы пишете t1*t2 при join. Это значит не арифметическое умножение а логическое (из математики множеств). Если Вы хотите пропихнуть арифметику Вы обязаны писать t1*index(t2) иначе индексы не имели бы такой популярности. В общем кто первый скажет слово Индекс - тот проиграл.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 07:31 27-12-2013
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover

Цитата:
Я так и думал что Вы немного не понимаете

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

Цитата:
пишете t1*t2 при join. Это значит не арифметическое умножение а логическое

вот его, Декартово произведение и имею в виду. какое же тут другое может быть

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 17:28 27-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004

Цитата:
вот его, Декартово произведение и имею в виду. какое же тут другое может быть

У Вас каша с комбинациями и индексами. Напомню (можете провикипежить), индексы были придуманы человечеством, чтобы не искать методом перебора всех комбинаций. При поиске по индексу уменьшается количество сравнений...
 
Например наша таблица это "куча", нет кластерного индекса. То есть данные не отсортированы, а вот ссылки в индексе отсортированы по значению поля. В классическом случае мы делим индекс (список ссылок) пополам. Берём среднюю ссылку и сравниваем значение поля с искомым. Если меньше, берём меньшую часть и снова делим пополам. Так мы делаем пока не найдём. То есть поиск в таблице с миллионом записей может быть равен трём значениям, хотя такой же поиск в таблице с тысячей записей будет равен десяти операциям сравнений.
 
Именно по этому количество операций сравнений равно функция от индекс.
Count(Join)=t1*index(t2),
Count(LeftJoin)=t1*index(t2)
 

Цитата:
это результат один и тот же, а вот количество комбинаций, которые просматриваются для получения результата - разные (хотя опять же, умный оптимайзер может догадаться)  

Во первых и результат один и тот же и исходные данные одни и те же. Начертите в Экселе две таблицы с пятью записями и найдите случай когда Вам понадобится разное количество сравнений. Если получится, то считайте, что Нобелевскую премию Вы заработали. С обоими join абсолютно необходимо одинаковое математическое усилие.
 

Цитата:
оптимайзер может догадаться

Оптимайзер может "догататься", что если простой фильтрующий join по маленькой табличке выполнить раньше следующих join, то меньше нужно сравнений. Относительно left join это не касается.
 
 
Добавлено:
Я не рассматриваю случаи с не классическими индексами и смешенной организацией памяти базы - диск + ОЗУ. Так же исключена статистика индексов и так далее. Всё это может повлиять на выбор следующего join для оптимайзера, в моём примере PLAN одинаковый.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 14:44 31-12-2013
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
Чисто теоретически - результаты при join не обязаны совпадать с результатами при leftjoin (т.к. при t1 left join t2 допускается отсутствие записей в t2 по условию leftjoin-а). То, что у Вас они одинаковые - так это by design, но ведь база догадаться об этом никак не может, ей никто не гарантирует, что для каждой записи в t1 всегда будут находиться соотв. записи в t2. Уже хотя бы поэтому будут разные алгоритмы обработки запросов. Как-то так.  
 
С наступающим Новым Годом

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 16:55 31-12-2013
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004
Ваше решение достаточно убедительно и является единственным. Версию про всякие количества рано исследовать. Вас с наступившим по старому. )

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 03:13 07-01-2014
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
С чем может быть связано, что по Local Engine база не зацепляется, хотя по Remote TCP\IP коннект удачный. Это связано не просто с Localhost, а именно с галочками Local\Remote. Мы переустановили сервер (Win7 32), даже с перезагрузками не помогло. Путь к библиотеке gds32 вообще никто не трогал. Правда одно недоразумение - база лежит в пути 'C:\'. Однако при тех же настройках IBExpert цепляется, штатный IBX цепляется, а вот FIB требует галочку Remote.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 11:14 09-01-2014
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Мы сделали следующее.
1) Установили 2.5.0.26074 Сервер (как мама велела).
2) Прописали путь к fbclient.dll (как бабушка велела).
 
После этого к базе на Рабочем Столе мы подсоединились, но вот на диске 'C:\' не получается. Хотя файл один и тот же, но пляски с бубнами остались. В общем процесс я запустил, но если кто знает ещё рецепты, прошу пишите.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 14:15 09-01-2014
egerLESHIK



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
 
а, ODBC Драйвер под firebird устанавливали?
На днях после переустановки Windows тоже столкнулся с тем, что к базе в один день есть подключение, в другой день нет. Причина оказалась банальной - соединение отклонял брандмауэр windows. Значит или отключаем его, или добавляем программы, работающие с базой в исключения.

Всего записей: 950 | Зарегистр. 24-03-2004 | Отправлено: 16:20 09-01-2014 | Исправлено: egerLESHIK, 16:25 09-01-2014
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
egerLESHIK
Спасибо, кстати скорее всего так и есть. Просто ODBC я ещё слышал, а вот что такое брандмауэр "я не знаю". У нас только папочка FireBird и море компьютеров куда его ставят. А интересно чем диск C отличается от рабочего стола? Ну да ладно, Windows сейчас без ODBC поставляют, замучил я Вас.
 
Да, забыл упомянуть самое смешное. Мы в дизайне прописали папочку на рабочем столе, а при запуске программы читалась база с Ц диска. Так вот, мы пол часа гадали почему реально коннект есть, а у нас, при запуске программы полный абзац. Когда поняли что базы разные, вопрос решился. Но я понимаю, например autorun.inf, но с папками я так и не понял.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 18:22 09-01-2014 | Исправлено: delover, 18:54 09-01-2014
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover

Цитата:
А интересно чем диск C отличается от рабочего стола?

возможно, правами доступа отличается

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 22:39 09-01-2014
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ant0ni02004

Цитата:
возможно, правами доступа отличается

 
Совершенно точно. Мы поставили пользователям те же галочки что и администраторам, и FireBird стал пускать к базе. Только учтите, что если поставите галочки, Windows будет шерстить все подпапки какие найдёт на диске. Естественно, сильно Вы не навредите, но так лучше не делать.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 08:43 10-01-2014
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » InterBase и FireBird: вопросы по работе и их решение


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru