Оптимизация union
OS: Win Vista Firebird: 2.1 SS Query select * from ( select ID, DOC_ID, OWNER_ID, 1 as TYPE_ID from DOC_TO_BUS union select ID, DOC_ID, OWNER_ID, 2 as TYPE_ID from DOC_TO_JUR union select ID, DOC_ID, OWNER_ID, 3 as TYPE_ID from DOC_TO_PHYS ) T where T.TYPE_ID = 1 Plan PLAN (T DOC_TO_BUS NATURAL) PLAN (T DOC_TO_JUR NATURAL) PLAN (T DOC_TO_PHYS NATURAL) Adapted Plan PLAN (T DOC_TO_BUS NATURAL) PLAN (T DOC_TO_JUR NATURAL) PLAN (T DOC_TO_PHYS NATURAL) Query Time Prepare : 15,00 ms Execute : 16,00 ms Avg fetch time: 0,80 ms Memory Current: 34 320 176 Max: 35 443 808 Buffers: 2 048 Operations Read : 0 Writes : 0 Fetches: 56 652 Enchanced Info: +--+---+---+-+ |Table Name| Records | Indexed | Non-Indexed | | | Total | reads |reads| +--+---+---+-+ |DOC_TO_BUS| 0 | 0 | 826 | |DOC_TO_JUR| 0 | 0 | 23295 | | DOC_TO_PHYS| 0 | 0 |4093 | +--+---+---+-+ Т.е. читает все 3 таблицы из объединения, хотя очевидно, что нужна только одна. Если вынести внутренний запрос в представление (view) картина не изменяется. Планируется ли как-нибудь обрабатывать подобные ситуации в оптимизаторе? -- Александр Замараев
отслеживание рекурсии
Привет народ. Тут достали юзера решил воткнуть проверку на рекурсию при отпуске товара благо не на процедурах и можно практически забыть про вложенность. Сделал естественно, но сижу и думаю. Предпологаю что при такой проверке будут проверятся кучи документов и чем дальше тем дольше будет это работать. Сейчас это делаю так получаю строки документа с которого буду списывать на каждую строку получаю строки документов с которых было списание (и так до тех пор пока null не встретися) WITH RECURSIVE T001_TREE as ( select T003_1, T001_1, T001_1b FROM T001 where T001.T003_1 ='lxB+drce4BabY2lGRT5ha2' union all select D2.T003_1, D2.T001_1, D2.T001_1b FROM T001 D1 join T001_TREE Db on D1.T001_1 = Db.T001_1b join T001 D2 on D2.T003_1 = D1.T003_1) select * from T001_TREE Но в этом случае получается что всегда буду перечитывать ворох документов. Решил проверить и действительно проверка 3 строк прошла аж за 22 минуты ужас. Когда идет проверка одной строки это еще ничего всего 0,044 но когда проверка всего это жуть. Поделитесь опытом мож еще чего подчерпну. Уровни здесь не прикрутить т.к. вложенность бесконечна это просто строки документов ссылающиеся на приход. Если сформировать таблицу кто к кому относится я думаю она скоро станет таким слабым местом что даже чет в ее сторону пока недумается. Хотя тогда будет все мгновенно отрабатывать.
Re: Оптимизация union
Tonal wrote: Планируется ли как-нибудь обрабатывать подобные ситуации в оптимизаторе? Вряд ли. -- Дмитрий Еманов
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"Vlad Khorsun" > > Ну думаю не стоит, ибо COMMIT RETAIN есть ) > > Мгм... я подумаю ещё... а пока можно в трекер занести На предмет проверки актуальности соединения? Если правильно понял, то занесу. > > НАПРИМЕР: > > Выполнили RDB$SET_CONTEXT, а потом давай из VIEW запросы писать. Ну > > а VIEW данные по контексту ограничивают. > > ...ибо это я не понял Это я так "спасибо" пытался сказать :) Есть задача: - Подключиться к другой БД. - Там установить контекстные переменные (VIEW на их основе данные фильтруют). - Повыполнять запросы к этим вьюхам. Если бы каждый раз было новое подключения, то такой бы фокус не прошёл. Понятно, что идея была не совсем такая, а чтобы и коннекты не плодить и время не транжирить на подключения. > Убить свой коннект хотел ? Должно убить, imho... А зачем ? Пробовал. Можно выполнить DELETE FROM MON$ATTACHMENTS несколько раз подряд. > Изврат :) Есть другие предложения? (риторика) :))) > Во-первых, должно убить и из своего коннекта, imho, а во-вторых можно и > без > 'localhost/3051'. учту про 'localhost', а "убить" себя нельзя!
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
> Вот зачем тебе свежие билды :) Ну а над кем мне издеваццо исче ? :) Над людьми нельзя, а то обратно на дурку запрут. Мне еще по выписке в прошлый раз доктор об этом предупреждал. Кошечек и собачек просто жалко. > > Сервер выживает ? Должен выдать ошибку про превышение лимита рекурсии > и ехать дальше. Так ? > > -- > Хорсун Влад Не знаю. Просто я "основательно" подготовился (гы-гы), запустил диспетчер задач... Когда ползунок списка процессов "уехал" далеко - нервы не выдержали. К тому же я это запустил с консоли корпоративного сервака клиента, коннектов 20 висело. :) Ну, в общем reset и массовый вопль в офисе. :) Дома посмотрю, как оно себя ведет. Да, кстати, лимит коннектов там какой ?
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
Vlad Khorsun wrote: а "убить" себя нельзя! На это пусть ДЕ отвечает :) Слава богу, АСТы сами себе не доставляются :-) Ибо нефиг. -- Дмитрий Еманов
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"PEAKTOP" > > И это ещё не полный список извращений. > > Ну, может здесь это уже стало бояном, не знаю, не видел. > Но все же, из раздела о практической проктостоматологии :) > > 1) CREATE TABLE AAA (TXTSQL VARCHAR(1024)); > 2) Вставляем в табличку одну запись содержания: > > EXECUTE BLOCK AS > DECLARE VARIABLE P_DB_NAME VARCHAR(255); > DECLARE VARIABLE P_SQL VARCHAR(1024); > BEGIN > SELECT FIRST 1 ATT.MON$ATTACHMENT_NAME FROM MON$ATTACHMENTS ATT > INTO :P_DB_NAME; > P_DB_NAME = '127.0.0.1:' || :P_DB_NAME; > SELECT FIRST 1 A.TXTSQL FROM AAA A INTO :P_SQL; > EXECUTE STATEMENT :P_SQL > ON EXTERNAL DATA SOURCE :P_DB_NAME > AS USER 'SYSDBA' PASSWORD 'masterkey'; > END > > 3) этот же самый скрипт выполняем с консоли. > > AMD Turion 2x64 "уходит в себя" за 12 секунд. :) Какой злостный хак. Вот ещё на 2.0 и 2.1 (в 2.5 пофиксили) можно потестировать толпу зарождающихся врЕменных блобов. Запускаешь и следи за памятью execute block as declare variable BLB blob SUB_TYPE TEXT; declare variable A VARCHAR(10); declare variable I INTEGER; begin BLB = 'X'; I = 0; WHILE (I < 3) DO BEGIN A = SUBSTRING(BLB FROM 1 FOR 1); I = I + 1; END end
Re: отслеживание рекурсии
Hello, Boltik! You wrote on Wed, 17 Dec 2008 15:06:22 +0700: BE> Тут достали юзера решил воткнуть проверку на рекурсию при отпуске товара BE> благо не на процедурах и можно практически забыть про вложенность. Евгений, ты остатки не хранишь из принцЫпу? Или кто-то из нас неправ? -- With best regards, Alex Cherednichenko.
EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
Такое поведение нормально? Firebird-2.5.0.21848-0_Win32_PEAKTOP -- execute block returns (TRAN_ID integer) as declare variable DB_NAME TYPE OF COLUMN MON$ATTACHMENTS.MON $ATTACHMENT_NAME; begin SELECT A.MON$ATTACHMENT_NAME FROM MON$ATTACHMENTS A WHERE A.MON$ATTACHMENT_ID = CURRENT_CONNECTION INTO :DB_NAME; EXECUTE STATEMENT 'select CURRENT_TRANSACTION from RDB$DATABASE' ON EXTERNAL 'localhost/3051:' || :DB_NAME AS USER 'SYSDBA' PASSWORD 'masterkey' into :TRAN_ID; SUSPEND; EXECUTE STATEMENT 'COMMIT WORK' ON EXTERNAL 'localhost/3051:' || :DB_NAME AS USER 'SYSDBA' PASSWORD 'masterkey'; EXECUTE STATEMENT 'select CURRENT_TRANSACTION from RDB$DATABASE' ON EXTERNAL 'localhost/3051:' || :DB_NAME AS USER 'SYSDBA' PASSWORD 'masterkey' into :TRAN_ID; SUSPEND; end = Execute statement error at isc_dsql_fetch :335544569 : Dynamic SQL Error 335544436 : SQL error code = -901 335544332 : invalid transaction handle (expecting explicit transaction start) Statement : select CURRENT_TRANSACTION from RDB$DATABASEData source : Firebird::localhost/3051:C:\_DBASES\AAA_2.5.FDB.
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"Alex Bekhtin" ... Такое поведение нормально? А что ты хотел этим сделать ? Добиться того, чтобы я запретил COMMIT\ROLLBACK в EXECUTE STATEMENT ? Так я это сделаю ;) -- Хорсун Влад
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"PEAKTOP" AMD Turion 2x64 "уходит в себя" за 12 секунд. :) Вот зачем тебе свежие билды :) Сервер выживает ? Должен выдать ошибку про превышение лимита рекурсии и ехать дальше. Так ? -- Хорсун Влад
Re: В чем смысл ? (пятничное)
>> А, так ты любитель фуллсканов с блокировкой таблиц? Прааативный :-D >> -- >> Regards. Ded. Ай, бля... Точно. Ведь эта фигня еще в JOIN-ах используется. Все. Пора в ежегодный запой. :) >> Ведь кроме ссылочной целосности, есть ещё и джоины по этим самым ссылкам, и >> как прикажешь теперь этот джоин выполнять? >> Полным перебором? ;) >> -- >> С уважением Горбонос Игорь Леонидович Ну не подумал я про это дело. Признаю. >> Oleg Matveyev >> Есть еще одна штука. >> Уникальный индекс сам по себе подсказка оптимизатору: >> уникальный индекс - гуд. >> нашел значение - стоп, дальше сканировать ненадо - второй записи с таким >> значением не будет. Да понял уже, понял. Во как накинулись-то все...
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
8-O Дайте две -- Regards. Ded.
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
> Аааа, так у тебя ещё и классик ! Ну а кто ж еще. > -- > Хорсун Влад > > PS а с рекурсией будет ограничение только для внутренних коннектов, для > внешних > невозможно даже распознать наличие такой рекурсии. А может max_db_connection_count в firebird.conf ? Ну, по дефолту "-1", а мне с моей паранойей доктор подскажет, сколько писать :)
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"PEAKTOP" ... Сервер выживает ? Должен выдать ошибку про превышение лимита рекурсии и ехать дальше. Так ? ... Не знаю. Просто я "основательно" подготовился (гы-гы), запустил диспетчер задач... Когда ползунок списка процессов "уехал" далеко - нервы не выдержали. К тому же я это запустил с консоли корпоративного сервака клиента, коннектов 20 висело. :) Ну, в общем reset и массовый вопль в офисе. :) Дома посмотрю, как оно себя ведет. Да, кстати, лимит коннектов там какой ? Аааа, так у тебя ещё и классик ! Скока ось сможет, столько и будет коннектов, потом обломится. Для супера быстрее настанет ограничение на 2 гига виртуалки на процесс, по идее. -- Хорсун Влад PS а с рекурсией будет ограничение только для внутренних коннектов, для внешних невозможно даже распознать наличие такой рекурсии.
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"PEAKTOP" > Ты уточняй: твое поведение или сервера ? Поведение сервера. > З.Ы. а я думал, что таких извращенцев как я поискать надо. Ан нет, не > перевелись еще на русской земле ... (чуть не написал "богатыри") :) По поводу извращенцев. Выглядит это странно, а что делать? Вот есть мониторинг в 2.5. Весь из себя красивый, но(!) не везде удобный, потому как обусловлен особым поведением, аля снимок на момент времени. Дима не раз объяснял, что как у борманов не хочет, потому как таблички должны быть вкупе валидны друг с другом. На этот случай появились автономки, как элемент-блок PSQL и как элемент EXECUTE STATEMENT. Вот пример получения объекта, нас вызвавшего: CREATE OR ALTER PROCEDURE GET_CALLER_NAME RETURNS ( OBJECT_NAME CHAR(31), OBJECT_TYPE SMALLINT) AS DECLARE VARIABLE TRAN_ID INTEGER; begin TRAN_ID = CURRENT_TRANSACTION; IN AUTONOMOUS TRANSACTION DO BEGIN select first 1 skip 1 CS.mon$object_name, CS.mon$object_type from mon$call_stack CS, mon$statements ST where CS.mon$statement_id = ST.mon$statement_id AND ST.mon$transaction_id = :TRAN_ID order by CS.mon$call_id ascending into :OBJECT_NAME, :OBJECT_TYPE; END SUSPEND; end аналогично и себя так можно получить и т.п. Ещё пример? Запросто! Хочу PRINT для отладки, а вот не его... Можно через внешние таблички, а вот неудобно. Ну что ж, сделаем через автономки: CREATE OR ALTER PROCEDURE PRINT( PRINT_DATA VARCHAR(32000)) AS begin in autonomous transaction do begin insert into print_out(PRINT_DATA) values (:PRINT_DATA); end end И это ещё не полный список извращений.
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"Alex Bekhtin" ... А что ты хотел этим сделать ? Добиться того, чтобы я запретил COMMIT\ROLLBACK в EXECUTE STATEMENT ? Так я это сделаю ;) Ну думаю не стоит, ибо COMMIT RETAIN есть ) Мгм... я подумаю ещё... а пока можно в трекер занести Вообще, оптимизация соединения EXECUTE STATEMENT с внешними датасорсами - это нужная вещь. Смотря что под этим понимать... НАПРИМЕР: Выполнили RDB$SET_CONTEXT, а потом давай из VIEW запросы писать. Ну а VIEW данные по контексту ограничивают. ...ибо это я не понял Вышел на это случайно. Прочитал в README.monitoring_tables.txt: DELETE FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID <> CURRENT_CONNECTION любопытство заставило задаться вопросом: "А что ели не указать условие?" И что?... ничего! Убить свой коннект хотел ? Должно убить, imho... А зачем ? Тогда стал копать в сторону: "А как же тогда <<саммо-отключиться>>" родилось нечто вида: execute block as declare variable DB_NAME TYPE OF COLUMN MON$ATTACHMENTS.MON $ATTACHMENT_NAME; begin SELECT A.MON$ATTACHMENT_NAME FROM MON$ATTACHMENTS A WHERE A.MON$ATTACHMENT_ID = CURRENT_CONNECTION INTO :DB_NAME; EXECUTE STATEMENT ('DELETE FROM MON$ATTACHMENTS WHERE MON $ATTACHMENT_ID = :CONN') (CONN := CURRENT_CONNECTION) ON EXTERNAL 'localhost/3051:' || :DB_NAME --WITH AUTONOMOUS TRANSACTION AS USER 'SYSDBA' PASSWORD 'masterkey'; end Изврат :) Во-первых, должно убить и из своего коннекта, imho, а во-вторых можно и без 'localhost/3051'. -- Хорсун Влад PS Заодно вроде как бага вылезла с оставшимся коннектом, сегодня посмотрю
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
> > И это ещё не полный список извращений. Ну, может здесь это уже стало бояном, не знаю, не видел. Но все же, из раздела о практической проктостоматологии :) 1) CREATE TABLE AAA (TXTSQL VARCHAR(1024)); 2) Вставляем в табличку одну запись содержания: EXECUTE BLOCK AS DECLARE VARIABLE P_DB_NAME VARCHAR(255); DECLARE VARIABLE P_SQL VARCHAR(1024); BEGIN SELECT FIRST 1 ATT.MON$ATTACHMENT_NAME FROM MON$ATTACHMENTS ATT INTO :P_DB_NAME; P_DB_NAME = '127.0.0.1:' || :P_DB_NAME; SELECT FIRST 1 A.TXTSQL FROM AAA A INTO :P_SQL; EXECUTE STATEMENT :P_SQL ON EXTERNAL DATA SOURCE :P_DB_NAME AS USER 'SYSDBA' PASSWORD 'masterkey'; END 3) этот же самый скрипт выполняем с консоли. AMD Turion 2x64 "уходит в себя" за 12 секунд. :)
Re: отслеживание рекурсии
> Евгений, ты остатки не хранишь из принцЫпу? > Или кто-то из нас неправ? > -- > With best regards, Alex Cherednichenko. Не обязательно дело в остатках. 1) Он может с LIFO\FIFO заморочился (матетматически, а не как это делают бухгалтеры тупо умножая общее количество остатков на последнюю цену прихода), вот и ищет партию ТМЦ, откудыва списывать. 2) Я как для ресторанов внедрял. И там есть така фишка: калькуляции на блюда, по которым идет расход компонентов со склада. А в калькуляции может быть полуфабрикат (например, курица отварная), которая тоже калькуляция и т.д. На практике 5-6 уровней вложенности для ресторана - это нормально. Я просто еще не потерял веру в людей. :)
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"Хорсун Влад" > А что ты хотел этим сделать ? Добиться того, чтобы я запретил > COMMIT\ROLLBACK > в EXECUTE STATEMENT ? Так я это сделаю ;) Ну думаю не стоит, ибо COMMIT RETAIN есть ) Вообще, оптимизация соединения EXECUTE STATEMENT с внешними датасорсами - это нужная вещь. НАПРИМЕР: Выполнили RDB$SET_CONTEXT, а потом давай из VIEW запросы писать. Ну а VIEW данные по контексту ограничивают. Вышел на это случайно. Прочитал в README.monitoring_tables.txt: DELETE FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID <> CURRENT_CONNECTION любопытство заставило задаться вопросом: "А что ели не указать условие?" И что?... ничего! Тогда стал копать в сторону: "А как же тогда <<саммо-отключиться>>" родилось нечто вида: execute block as declare variable DB_NAME TYPE OF COLUMN MON$ATTACHMENTS.MON $ATTACHMENT_NAME; begin SELECT A.MON$ATTACHMENT_NAME FROM MON$ATTACHMENTS A WHERE A.MON$ATTACHMENT_ID = CURRENT_CONNECTION INTO :DB_NAME; EXECUTE STATEMENT ('DELETE FROM MON$ATTACHMENTS WHERE MON $ATTACHMENT_ID = :CONN') (CONN := CURRENT_CONNECTION) ON EXTERNAL 'localhost/3051:' || :DB_NAME --WITH AUTONOMOUS TRANSACTION AS USER 'SYSDBA' PASSWORD 'masterkey'; end
Re: В чем смысл ? (пятничное)
PEAKTOP wrote: А, так ты любитель фуллсканов с блокировкой таблиц? Прааативный :-D Ай, бля... Точно. Ведь эта фигня еще в JOIN-ах используется. Да хрен-то с ними, с джойнами. А как ты намеревался проверять целочную ссылостность на фоне многопользовательской работы с таблицами на обоих концах ФК? Частично незакоммиченной, кстати. Работы. Все. Пора в ежегодный запой. :) Эт всегда полезна :-) -- Regards. Ded.
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
> Такое поведение нормально? > Ты уточняй: твое поведение или сервера ? З.Ы. а я думал, что таких извращенцев как я поискать надо. Ан нет, не перевелись еще на русской земле ... (чуть не написал "богатыри") :)
Re: EXECUTE STATEMENT - EXTERNAL SOURCE - COMMIT WORK - ошибка
"Alex Bekhtin" ... "Vlad Khorsun" > Ну думаю не стоит, ибо COMMIT RETAIN есть ) Мгм... я подумаю ещё... а пока можно в трекер занести На предмет проверки актуальности соединения? Если правильно понял, то занесу. На предмет потери внешней тр-ции после 'COMMIT WORK'. Движок должен или запрещать это, или учитывать. Есть задача: - Подключиться к другой БД. - Там установить контекстные переменные (VIEW на их основе данные фильтруют). - Повыполнять запросы к этим вьюхам. Если бы каждый раз было новое подключения, то такой бы фокус не прошёл. Вообще-то нет гарантии, что будет повторно задействованно тоже самое подключение. И до релиза я не буду это ни подтверждать, ни опровергать. Понятно, что идея была не совсем такая, а чтобы и коннекты не плодить и время не транжирить на подключения. Где-то так и было :) Убить свой коннект хотел ? Должно убить, imho... А зачем ? Пробовал. Можно выполнить DELETE FROM MON$ATTACHMENTS несколько раз подряд. Изврат :) Есть другие предложения? (риторика) :))) Не извращаться. Хотя... это ж кто на такое согласится ? :) Во-первых, должно убить и из своего коннекта, imho, а во-вторых можно и без 'localhost/3051'. учту про 'localhost', а "убить" себя нельзя! На это пусть ДЕ отвечает :) -- Хорсун Влад