Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» InterBase и FireBird: вопросы по работе и их решение

Автор: delover
Дата сообщения: 12.05.2012 18:49


Фраза - поток сознания происходит из того что некий индивидуум может пьян а может ослеплён мыслью, но он не может донести - доказать... Говорит всё понятно но мысли то нет или не видно. В языке обывателей это выражение можно заменить на равнозначное - "не грузи меня". В сознании обывателя, - если сразу не понятно то это поток сознания. Теряется привкус того что это сказано к месту. Рекоммендяция не использовать.
Автор: AlexCoRu
Дата сообщения: 12.05.2012 22:47
delover, хватит уже разорятся. ИТ зашли в тупик, впрочем как и всё остальное. Прогресса не будет, эксплуатируй то что есть.

Добавлено:

Цитата:
под конец дня полностью разочаровался в своей идее
Период внедрений кончился, пошёл процесс эксплуатации )))
Отсюда разрыв шаблонов - на внедрении срубают бабки, за эксплуатацию никто не платит.
Автор: SevereK20
Дата сообщения: 12.05.2012 22:56
Может не совсем в тему.. Есть ли у кого-нибудь исходники программ на delphi, илюстрирующие работу с FB базой...
Автор: AlexCoRu
Дата сообщения: 12.05.2012 23:11

Цитата:
Есть ли у кого-нибудь исходники программ на delphi, илюстрирующие работу с FB базой


Цитата:
селект идёт не на прямую из процедуры а именно в селект запросе с ордербай по апперкейс имени. Потом это скармливается гридине у которой уже стоит сортировка - она сортирует по другому. Потом Filtered := false когда он и так false. Потом блок который востанавливает сортирувку в других гридинах где это нужно востановить, то есть сортируется ещё раз. И потом видимо компоненты поменялись, потом считываются установки из реестра и сортируется ещё раз.

Как-то так )))

Добавлено:
SevereK20, если серьёзно то Всего-то хотелось иметь несколько независимых курсоров на один набор данных

Добавлено:
Как вам нравится из справки QuantumGrid
Цитата:
In Grid mode, the data controller's performance is better, but features such as automatic sorting, filtering and summary calculations are disabled. You have to write appropriate event handlers (OnSortingChanged, Filter.OnBeforeChange, OnAfterSummary) to perform these actions.
И сразу же, мордой об стену
Цитата:
Grid mode is automatically switched off when grouping is applied to a grid view.
Автор: SevereK20
Дата сообщения: 13.05.2012 00:42
AlexCoRu
не понял....
я имел ввиду исходник программы, илюстрирующей общую работу с фб базой - учет многопользовательской работы и других аспектов.
Автор: AlexPetrovich
Дата сообщения: 14.05.2012 12:30
SevereK20
Зависит от компонентов какими будешь пользоваться.
Обычно с компонентами идет папка Demo с примерами.

И советую сходить сюда - http://ibase.ru/ раздел "Документация и статьи"

Автор: SevereK20
Дата сообщения: 14.05.2012 14:09
AlexPetrovich
FIBPlus... читал книги... но сухо как-то - хотелось бы посмотреть на работающую систему, а не рассматривать урывки. В папках демо примеры по работе с отдельными компонентами.
Автор: delover
Дата сообщения: 15.05.2012 17:33
SevereK20
Вы очень уместно спросили. Я Вам предложу следующее. Я не представляю себе работы без IBExpert.
1) Копируем IBExpert и создаём базу test. Там можно переключить интерфейс на русский язык.
2) Накатываем на созданную базу следующий скрипт CTRL+F12.
[more]
Код: [no]
/* Create Table... */
CREATE TABLE TABLE1(ID INTEGER NOT NULL,
GRADE_ID INTEGER,
PARENT_ID INTEGER,
"VALUE" VARCHAR(2));



/* Create Procedure... */
SET TERM ^ ;

CREATE PROCEDURE NEW_PROCEDURE AS
BEGIN EXIT; END
^


/* Create index... */
SET TERM ; ^

CREATE INDEX TABLE1_IDX1 ON TABLE1(GRADE_ID);

CREATE INDEX TABLE1_IDX2 ON TABLE1(PARENT_ID);


/* Create generator... */
CREATE GENERATOR GEN_TABLE1_ID;


/* Create Primary Key... */
ALTER TABLE TABLE1 ADD CONSTRAINT PK_TABLE1 PRIMARY KEY (ID);

/* Alter Procedure... */
/* Restore proc. body: NEW_PROCEDURE */
SET TERM ^ ;

ALTER PROCEDURE NEW_PROCEDURE AS
declare variable ID integer;
declare variable PAR_ID integer;
begin
id = 1;
par_id = null;
while (id < 5*1000*1000) do
begin
if (:id > 1000*1000+1 and :id < 1000*1000+24) then
begin
par_id = :id - 1000*1000;
end
if (:id = 1000*1000+25) then
begin
par_id = null;
end
insert into TABLE1 (GRADE_ID, PARENT_ID, "VALUE")
values (:ID, ar_id, null);
id = :id + 1;
end
end
^

/* Creating trigger... */
CREATE TRIGGER TABLE1_BI FOR TABLE1
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.id is null) then
new.id = gen_id(gen_table1_id,1);
end
^


/* Alter Procedure... */
/* Create(Add) Crant */
SET TERM ; ^

GRANT ALL ON TABLE1 TO SYSDBA WITH GRANT OPTION;
[/no]
Автор: delover
Дата сообщения: 15.05.2012 20:23


Ну тогда я сделаю between. Есть ещё одно неприятное качество SQL, которое можно увидеть пройдя первый вопрос. - Среди приджойненных индексов, импровизация, вдруг будет именно в одной записи взаимоисключающее условие и оно не будет просчитываться полностью, будет оптимизировано в момент компиляции, хотя бы одно условие.
Автор: SevereK20
Дата сообщения: 15.05.2012 21:17
delover
в том-то и дело, что я прошу пример проги на делфи для того чтобы увидеть как с клиентского приложения происходит работа с базой данных. как правильнее использовать блокировки, транзакции и прочее. именно их применение из клиентских приложений, а не теория.
Автор: delover
Дата сообщения: 16.05.2012 06:37
SevereK20
Про транзакции - их две на чтение и на запись. Про блокировки в одной программе я работал там 2 года мы использовали блокировки везде. В другой программе 2 года там блокировок нигде не использовалось. Обе программы замечательны, но написаны по разному, так что я не скажу как правильно будет, это зависит от стиля программирования, который вы выберете. Прочее - например Алертеры, то же что с блокировками - всё зависит от стиля и постановки работы пользователей в вашем приложении. Блокировки можно заменить на 1 дополнительное поле в таблице. Алертеры можно заменить на один единственный сервер-порт прописанный в таблице настроек. Транзакции лучше 2, но это тоже от стиля зависит - есть стиль вообще без транзакций.
Автор: delover
Дата сообщения: 17.05.2012 07:17
AlexCoRu

Цитата:
Отсюда разрыв шаблонов - на внедрении срубают бабки, за эксплуатацию никто не платит.

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

Код:
select Tab1.* from
(select * from table1 t1
where t1.parent_id between 5 and 5) Tab1
join
(select * from table1 t2
where t2.grade_id between 1 and 3000000) Tab2
on tab1.id = tab2.id
PLAN JOIN (TAB1 T1 INDEX (TABLE1_IDX2), TAB2 T2 INDEX (PK_TABLE1))
Автор: AlexPetrovich
Дата сообщения: 17.05.2012 11:38
delover

Цитата:
6) Выполним на базе селект
select * from table1 t
where t.parent_id between 5 and 5 and
t.grade_id between 0 and 3000000
- хоть как оптимизируйте уже 100 миллисекунд.


И что ?
Это сильно принципиально ? Юзер сможет заметить разницу 1 и 100 мс ?

И вообще SQL и СУБД - это универсальный инструмент, который предназначен для решения общих задач.
Да FB не идеален, там нет например кластерных индексов, и оптимизатор изредка тупит и выбирает не самый оптимальный план. Но для этого и существует разработчик, который знает что у него за данные и как они распределены.

Конечно, каждый конкретный случай можно разложить по полочкам и оптимизировать.
Но стоит ли оно того? Оптимизировать нужно только то, что реально необходимо, а не все подряд.

Вот что вам даст ускорение одного запроса с 100 до 1 мс ?


Приведите пример реальной задачи где это нужно, а не сферического коня в вакууме.
Автор: X11
Дата сообщения: 17.05.2012 11:49

Цитата:
Вот что вам даст ускорение одного запроса с 100 до 1 мс ?


когда этот проверяется на 1000 записях, то оно понятно, что разницы нет, но когда таблица вырастает до 100 тыщ или мульёна.... то разница уже сильно заметна и тогда приходится выполнять редизайн приложения.
Автор: AlexPetrovich
Дата сообщения: 17.05.2012 12:22
X11

Цитата:
когда этот проверяется на 1000 записях, то оно понятно, что разницы нет, но когда таблица вырастает до 100 тыщ или мульёна....


Опять про сферического коня... Пример реальной задачи где ?

К тому же этот запрос как раз и работает с таблицей в которой 5 000 000 записей и ее размер ~350 МБ.

По моему 100 мс - не так и плохо.

Добавлено:
delover

Цитата:
Выполним на базе селект
select * from table1 t
where t.parent_id between 5 and 5 and
t.grade_id between 0 and 3000000
- хоть как оптимизируйте уже 100 миллисекунд.


И кстати - откройте для себя хинты.

"Оптимизируем" немного этот запрос:
select * from table1 t
where t.parent_id between 5 and 5 and
t.grade_id+0 between 0 and 3000000

И "внезапно" - он выполняется за 0 мс

Можно просто к исходному запросу приписать план
PLAN (T INDEX (TABLE1_IDX2))
Эффект тот же.

И не нужно переписывать в 3 сджойниных подзапроса...
Автор: SERGE_BLIZNUK
Дата сообщения: 17.05.2012 13:32

Цитата:
И кстати - откройте для себя хинты.

AlexPetrovich, а можно чуть-чуть "разжевать" - объяснить для тех, "кто в танке" (я себя имею в виду сейчас, если что... :) ), что за хинты имеются в виду?!
Автор: AlexPetrovich
Дата сообщения: 17.05.2012 15:52
SERGE_BLIZNUK
Хинты - подсказки серверу выполнить запрос наилучшим образом.
В данном случае в таблице 5 млн записей, а второе условие
t.grade_id between 0 and 3000000
выбирает из них 3 млн, т.е 60% объема. Выборка с использованием индекса по t.grade_id получается неэффективной.

Но так как есть первое условие
t.parent_id between 5 and 5
которое выбирает только 1 запись, то индексный поиск по второму в принципе лишний.

Поэтому второе условие записываем в виде
t.grade_id+0 between 0 and 3000000
где (+0) - приводит к тому, что с левой стороны условия появляется выражение и по нему не будет использоваться индексный поиск. Соответственно меняется план запроса и используется только один индекс, который в данном конкретном запросе "полезен".

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

В данном примере на 5 млн записей только у 25 из них прописан parent_id, у остальных null.
Т.е. очень не равномерное заполнение, поэтому оптимизатор выбрал не самый скоростной план.
Но это скорее исключение, т.к. стоит немного поменять цифры в параметрах запроса и предложенный оптимизатором план станет лучшим по скорости.

Индексы - это не всегда полезно. Нужно думать как они будут использоваться. А то повесят на все 30 полей в таблице индексы, а потом вопросы - почему такие тормоза ?
Автор: delover
Дата сообщения: 17.05.2012 20:35

Цитата:
Это сильно принципиально ?  Юзер сможет заметить разницу 1 и 100 мс ?


Рад что уже появляется некоторое взаимопонимание, хотя и неполное. Теперь когда Вы гораздо лучше представляете о чём идёт речь, я повторюсь. Вернёмся к тому что я уже писал. Предположим Вы пытаетесь оптимизировать приложение разработанное не Вами и это приложение огромное (тривиальный случай). Назовём неоптимальный селект "NOS2" а оптимальный селект "OS2". Теперь смотрим на запрос:

Код: select * from bigsel bs
join (OS2)
join (OS3)
where
id between 0 and 10000 and exist (OS4) and
exist (OS5)
Автор: AlexPetrovich
Дата сообщения: 18.05.2012 13:16
delover

По моему пытаться делать оптимизацию изобретая нестандартные SQL - это путь в никуда.
Никто ради вашей задачи не будет этим заниматься.
Надо использовать те инструменты, что уже существуют.

Если приложение "огромное", то заказчик должен быть готов выделить на это соответствующие ресурсы, и возможно лучше в этом варианте окажется полностью переписать слой приложения который работает с БД.

Цитата:
Предположим Вы прописали все планы в хранимой процедуре а потом случайно переименовали некоторые индексы но не делали перекомпиляцию хранимых процедур. И плюс к этому обнаружили косяки только тогда когда стали переходить на новую версию сервера.

А разработчик вообще-то работу работает или "случайно" в кнопки тыкает ?
Значит не получит зарплату и в следующий раз будет внимательнее проводить тестирование.
Автор: salexn1
Дата сообщения: 18.05.2012 14:53

Цитата:
t.grade_id+0 between 0 and 3000000  

На MSSQL такие штуки не прокатят...
Можете не пробывать
Автор: AlexPetrovich
Дата сообщения: 18.05.2012 17:01
salexn1
Почему ?

Запрос вообще не выполнится
или индекс по t.grade_id продолжит использоваться ?

Не могу проверить сам. MSSQL не установлен.
Автор: delover
Дата сообщения: 18.05.2012 18:06
salexn1
Мне кажется AlexPetrovich неправильно сомневается, я тоже перепроверю. Но сейчас я в онлайн качаю танка - это тигр оборотень, жена маршал создатель.

Добавлю
Современные компиляторы не способны собрать программу позволяющую использовать возможности SQL.
Автор: salexn1
Дата сообщения: 21.05.2012 10:29
AlexPetrovich
Продолжит юзать индекс. Шибко умный оптимизатор у MSSQL... В Оракле - прокатывали такие штучки (в 9 по-крайней мере)
Автор: AlexPetrovich
Дата сообщения: 22.05.2012 09:02
delover

Цитата:
Современные компиляторы не способны собрать программу позволяющую использовать возможности SQL.

Жжошь!
Качай тогда лучше танка - надеюсь это у тебя получается лучше.
Автор: delover
Дата сообщения: 22.05.2012 17:41
AlexPetrovich
Петровичь, я своими руками пишу в базу индексы на группу полей. Думаю Танка качать - лучше.
Автор: YuriyRR
Дата сообщения: 23.05.2012 07:26
delover

Цитата:
Думаю Танка качать

О чем это вы?
Автор: delover
Дата сообщения: 23.05.2012 21:56
YuriyRR
Оффтоп щас заработаю. Это онлайн игра, танк - персонаж который собирает максимальное количество ударов. Все бьют по нему... Так и не открыл хинты.
Автор: vetal71
Дата сообщения: 31.05.2012 15:27
всем привет.
есть таблица с полем itm_order типа varchar(10). заполнена следующими значениями 1, 2, 3, 4, 11, 111, 112, 1111
необходимо после сортировки получить следующий порядок:
1
11
111
112
1111
2
3
4
при обычной сортировке получается 1,11,1111,112
пробовал тип поля integer - получается 1,2,3,4,11...
может есть у кого какие мысли ?

Добавлено
должно получиться так:
1.
1.1.
1.1.1.
1.1.2.
...
1.1.11.
2.
2.1.
...
3.
...
4.
...
с точками я тоже пробовал, результата не меняет
Автор: salexn1
Дата сообщения: 31.05.2012 15:50
vetal71

Попробуй, мот прокатит

select itm_order from t1
order by SUBSTRING( itm_order from 1 for 1)

З.Ы. Не... Не прокатит

Добавлено:
vetal71
1111 - это 1.111 или 1.1.11 или 111.1 и т.д.
или это всегда 1.1.1.1, т.е. не может быть числа состоящего из 2-х и более цифр?


Добавлено:
Просто если мое предположение верно, можно попробовать придумать функцию, которая бы вычисляла какую-нить величину и сортировать по ней.
Ну например, т.к. у вас varchar(10) можно предположить, что макс кол-во цифр в числе 10. Придумываем функцию типа такую

123 = (10-1)*(10^10) - 2*(10^9) - 3*(10^8) - 0*(10^7) - 0*(10^6)...


Автор: ant0ni02004
Дата сообщения: 31.05.2012 17:51
vetal71

приводить всё к единому виду и сортировать по нему. нужно конечно знать какого вида данные
т.е.
2.2.2.2 приводим к 02.02.02.02 - тогда оно попадёт перед 11.00.00.00
2 приводим к 02.00.00.00 итд

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

Предыдущая тема: Сравнение двух строк


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.