Pull to refresh

Comments 32

Алексей такой вопрос, если ключ состоит из Varchar то это намного снижает производительность ??
Какие советы можете дать по повышению производительности Файрберд ??
конечно снижает. числовые столбцы и меньше по размеру, и быстрее обрабатываются.
А почему «ключ varchar»? Обычно ключ все-таки int/bigint, а в varchar хранится что-нибудь вроде «товарного номера» из букв и цифр.
Про guid отдельная песня — есть такое мнение, что guid ничем не лучше bigint. А особенно хуже тем, что guid плохо упаковывается, т.е. он генерируется «не подряд». Так что и столбец и индекс по нему будут «толще» последовательного bigint.

я еще добавлю, что разница достаточно быстро проверяется нагенерить ~10 миллионов значений не проблема, на них уже разницу можно увидеть.
У ключей varchar есть одно огромное преимущество в сравнении с целочисленными ключами, которое часто перевешивает их проблемы с производительностью — они читабельны. Вы можете открыть таблицу и сразу понять, о каких данных в связанных таблицах идёт речь. Возможность сразу видеть, что вот эта запись вставлена пользователем IVANOFF, а не выяснять в таблице Users, кто прячется под номером 34555, здорово экономит время при отладке приложений или «разборе полётов» во время каких-либо инцидентов, которые требуют анализа прямо в базе данных.
есть старая статья Тенцера — «Естественные ключи против искуственных ключей». По-моему там все эти вопросы расписаны раз и навсегда. :-)

С моей точки зрения — отладка это, конечно, удобно, но для баз в десятки и сотни гиг проигрыш в производительности уже будет заметным. Алексей рядом приводил разницу между GUID и bigint. На более коротком и более осмысленном varchar-ключе разница будет меньше, но все же будет.
Тут вопрос больше в плоскости проектирования запросов, индексов и т.д. Вот у меня, к примеру, сейчас открыта база Dynamics NAV на 25Гб всякой гадости. Правда, не FB, а MS SQL, но не суть важно. Я делаю запрос на выборку с джойном из десятка таблиц, из которых две 16 млн записей, одна 2.6 млн, и еще три по миллиону, джойн идёт по внешним ключам, все ключи естественные, и соответственно varchar'ы, ну и естественно, фильтр по нужному мне диапазону. Отрабатывает за полсекунды. Вероятно, числовые были бы эффективнее, но производительность все равно достаточна, чтобы пожертвовать ей в пользу удобства.
А так, конечно, все случаи разные, где-то такой подход годится, где-то нет, в общем, серебряную пулю тут искать нет смысла.
Согласен. Есть масса вещей (и трюков), которые противоречат теоретическим правилам разработки БД, но зато сильно улучшают производительность — денормализация, дублирование данных, и т.д.
Так что серебряная пуля в каждом случае своя.
Хотелось лишь дополнить ответ Дмитрия ( http://habrahabr.ru/post/267211/#comment_8580745 ).

Все вопросы типа «что за юзер скрывается под номером ...» очень запросто решаются однажды составленными и сохраненными запросами, использовать которые не требуется много времени. Хранить их можно как в отдельных файлах вне базы, так и в самой базе в специально имеющихся именно для таких случаев структурных объектах: проекции(view's) и хранимые процедуры.
Да в том то и дело, что этого хочется избежать. Написать «select Login from Users where ID=<>» ничуть не дольше, чем открыть файл с сохраненным запросом. Но это тоже время и лишнее действие, особенно если это приходится делать часто. По моему опыту, есть ряд ситуаций, когда естественный ключ практически всегда удобнее суррогатного. Это логин пользователя, код элемента справочника (системный номер контрагента, товара и т.д.), и системный номер документа. Они гарантированно уникальные (кроме логина в редких случаях), они участвуют во всех выборках, и они сразу предоставляют пользователю нужную информацию об объекте.
Юзеры иногда просят поменять свой логин. Люди, что с них взять :)
Это еще один ключевой момент: лично я считаю, что в правильной ИТ-политике смена логина должна быть наглухо запрещена. Логин — это как ДНК пользователя, даётся ему от рождения и так на всю жизнь :)
Сотрудник может менять фамилию, паспорт и т.д., но логин менять не должен. С практической точки зрения смысла в этом нет никакого, а технические проблемы и неудобства это вызывать может. Где-то не сработала синхронизация между системами, где-то логин в ЭЦП участвует и т.д.
Не соглашусь с вами. Криворукий помощник админа может вбить транслитерацию фамилии сотрудника с ошибкой, и что делать в таком случае?
Формат и нумерация естественного ключа может в любой момент измениться по независящим от разработчика причинам. В моей практике (в прошлом веке, еще на FoxPro) так ВНЕЗАПНО изменился формат кадастровых номеров, использовавшихся по всей базе и считавшихся, в среде использовавших его людей, незыблемым как Советский Союз.
Я ж специально написал «системный номер». Понятное дело, что дарованная государством нумерация никогда не бывает стабильной. Ну а внутрикорпоративная нумерация как правило живёт столько, сколько живёт ваша информационная система.
конечно ничем не дольше. пример из давнего прошлого: отдельно таблица действий и отдельно таблица юзеров. Построена проекция vw_action_user на основе запроса для построения рапорта за сегоднешний день
select * from action a, users u where a.usr_id=u.id and a.a_date = 'today'.

вызов этой проекции select * from vw_action_user всегда выводил нужные данные для рабочей смены, как в отчете так и в реальном времени для просмотра. А для забывчивых начальников смены не успевших вовремя оформить отчет существовала хранимая, которая делала тоже самое но с указанной в параметре датой:
select * from sp_action_users('01.01.2005')

что уж сложного и ленивого? особенно со средствами генерации отчета в виде иконки, клик на которой приводил к мокрой спине сотрудника.
Поймите, для регулярных запросов это вообще не важно. Всё, что отображается в отчётах/стандартных представлениях, может быть один раз написано и забыто. Читабельные данные важны как раз для нерегламентированных работ. Например, когда ваш vw_action_user перестанет выводить нужные данные, и потребуется полезть в исходные таблицы, чтобы разобраться, почему так произошло. А в сложных базах с тысячами объектов и кучей софта, который к ним обращается, и постоянными доработками/изменениями, такая потребность возникает часто.
особенно хуже тем, что guid плохо упаковывается, т.е. он генерируется «не подряд»

А почему его нельзя генерировать последовательно?
в Firebird используется штатная функция GUID операционной системы, насколько я в курсе. Потому он такой, какой есть, т.е. не последовательный.
Но мысль хорошая. Я как-то экспериментировал с «переворачиванием» GUID, у меня получилось что последовательные номера упаковываются в 4 раза лучше чем.
Разработчикам передадим, может успеют в 3.0 добавить нечто такое.
Если сравнивать INT64 и GUID (36 символов, генерированный), то вставка в таблицу с первичным ключом на INT64 (последовательным) в 3 раза быстрее, чем в таблицу с первичным ключом на такой VARCHAR. Конечно, случай крайний, т.к. сравниваем монотонный ключ и рандомизированный, но многие используют GUID таким образом. Так делать не надо — используйте INT64 для PK.
Производительность индекса по выборке тоже может быть серьезно хуже из-за большего объема индекса и, соответственно, индексных чтений.
Кстати говоря, мы производительность вставок и прочих операций подробно рассматривали на последнем семинаре 5 июня.
Система которую разрабатывали работает в 16 филиах, и генерация varchar в каждом филиале своя, Я сразу понял что снижает Left joiny, по всей видимости не все знают что поиск по строке дольше чем по int.

Кто нибудь знает если перевести на firebird 64 бита, то насколько производительность повысится ??
Наверное, в вопросе следует читать «на INT64»?
Повысится на небольшую величину.
Но вообще в производительности несколько компонентов: настройки Firebird, производительность и планы SQL запросов, управление транзакциями с целью минимизации количества версий записей, оптимальная структура данных.

Для начала попробуйте использовать оптимизированные конфигурационные файлы: ib-aid.com/ru/optimized-firebird-configuration
Ну и приходите к нам на семинары.
Нет, у нас стоит Server 64 bit, а вот сам Firebird 32 бита, из-за того что UDF-ки 32 битные ))
Это довольно частая ситуация, когда используют 32 битный Classic на 64-битной ОС. Прирост производительности при переходе с 32 на 64 бита очень невелик, и только для CPU-intensive операций. Если у вас запросы упираются в диск (а это наиболее частый случай, если не SSD 6G), то его не будет заметно. Основная причина для перехода с 32 битной архитектуры на 64 битную не скорость вычислений, а расширение лимита адресуемой памяти.
на CS разницы почти не будет.
использовать 32битные SS и SC на 64битной ОС, конечно, не нужно, просто из-за лимита памяти для 32битных приложений (на CS это не влияет).

Если сравнивать абстрактно, то приложения, которые потребляют CPU и память якобы быстрее в 64битном варианте примерно на 10-20%. Одновременно, они на столько же потребляют больше памяти из-за удвоенного размера указателей.
Я как-то сравнивал SS на Vista 64bit (если не ошибаюсь), у меня с 64битным ФБ получился выигрыш в 5-7%, потому что у СУБД больше работы с диском, чем с памятью и процессором.
Открыл произвольное место:
Так же, как и предложение WHERE ограничивает строки в наборе данных, теми
которые удовлетворяют условию поиска, с той разницей, что предложение HAVING
накладывает ограничения на агрегированные строки сгруппированного набора.

Как-то не очень по-русски написано.
Нашёл баг, открываю по вашей ссылке «трекер разработчиков», но там раздел файлы.
Где трекер то?
Интересно, при переходе с 2.5 на 3.0 будут breaking changes (запросы/процедуры, которые точно надо переписать)?
Не так много.
Некоторые смешения явных и неявных JOIN запретили. (этого вообще быть не должно)
Стабильность курсора поправили. Я надеюсь этот баг никто не использовал как фичу.
В некоторых случаях могут возникнуть проблемы в PSQL из-за введённой фичи когда можно использовать ссылку на курсор как переменную только для чтения.
Ну и просмотреть не напарываются ли ваши идентификаторы на новые ключевые слова.

Надо попробовать сделать backup/restore и если он пройдёт нормально, то уже хорошо. Ну а дальше тестировать вашу систему.
Хороший сервер, но приходится частенько от него отказываться из-за зарезервированных слов. Их нельзя использовать не только там, где они имеют значение по контексту, но и везде.
Например, VALUE — имеет значение только в определении ограничений для домена, но назвать столбец таблицы так нельзя. Берешь готовую систему — на любой сервер встает, на FB не хочет, и только потому, что там столбец VALUE — криминал
Не квотировать идентификаторы — это всё равно, что игнорировать unicode.

Зрелая система должна квотить все идентификаторы (таблиц, столбцов, процедур).
И тогда хоть по-русски называй их
create table "select" ("value" integer primary key, "Столбец2" varchar(10));
select "value" from "select"


Например, 1с все идентификаторы в запросах оборачивает.
Ну, 1с — одна такая, её приходится брать в расчет.
А в «зрелых» системах fb в расчет не принимают, там oracle, pgsql, mysql, на крайний случай — hsql (я про java). Квотировать идентификаторы — значит, вносить в рабочий код дополнительные метаданные, и ради fb никто этого делать не станет. Просто используют одну из альтернативных СУБД.
Так что более гибкая политика идентификаторов в версии 3.5, скажем, позволила бы fb поконкурировать со «старшими», и пошла бы только на пользу
Sign up to leave a comment.

Articles