Здравствуйте, <Аноним>, Вы писали: А>В интербайсе прокатывает вот такой запрос, который удалит все записи кроме одной с повторяющимся id.
Нет, он удалит все дублирующиеся записи:
id value
-- -----
01 red
02 green
02 green
03 black
=>
id value
-- -----
01 red
03 black
а надо
id value
-- -----
01 red
02 green
03 black
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Особенности Interbase
От:
Аноним
Дата:
18.03.04 13:52
Оценка:
Здравствуйте, Sinclair, Вы писали:
На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться
Здравствуйте, <Аноним>, Вы писали: А>На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться
Охренеть! Специально поставил Interbase 6.5 для проверки. Я и раньше знал, что Interbase — редчайший отстой, но чтоб настолько жидко...
тест 1:
create table test(id int, val char(5));
insert into test values(1, 'red');
insert into test values(2, 'green');
insert into test values(3, 'blue');
insert into test values(2, 'green');*/
delete from test
where test.ID in (select id from test GROUP BY id HAVING count(id)>1);
select * from test;
Результат:
id value
-- -----
01 red
02 green
03 blue
Давайте убедимся, что это — страшный косяк. Попробуем вычислить предикат в условии Delete вручную и скормить уже его:
create table test(id int, val char(5));
insert into test values(1, 'red');
insert into test values(2, 'green');
insert into test values(3, 'blue');
insert into test values(2, 'green');*/
/* А вот так можно убедиться в том, что в in стоит именно эта коллекция:*/select id from test GROUP BY id HAVING count(id)>1;
delete from test
where test.ID in(2);
select * from test;
Результат:
id value
-- -----
01 red
03 blue
Здорово, да? То есть у нас результат запроса зависит от порядка вычисления аргументов. Мы вроде как сделали эквивалентную замену (а ведь SQL — это функциональный язык), а результат изменился. Другая особенность в том, что если бы у нас записи с ID = 2 различались в поле val, то результат запроса вообще получается неопределенным.
В общем, ребята, Interbase — не RDBMS. Нельзя ее применять. Самые простые и очевидные вещи сделаны там через ухо.
... << RSDN@Home 1.1.3 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
delete from Table1
where Table1.ID in (select id from Table1 GROUP BY id HAVING count(id)>1)
А>На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться
в принципе это логично... но это не работает.
я пробовал на ms sql
Здравствуйте, ilya_ny, Вы писали:
_>Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться _>в принципе это логично...
Это абсолютно не логично, и ни кто, кроме Интербейса, таких вольностей себе не позволяет.
Здравствуйте, Sinclair, Вы писали:
S>Здорово, да?
Не то слово...
А интересно, какой-нибудь INSERT INTO table ... SELECT ... FROM Table, в бесконечный цикл это чудо вгонит?
Или update не шибко не тривиальный?
Самое прикольное, что этот баг практически не пофиксишь, поскольку я более чем уверен, что умельцами уже написана куча кода в расчете на эту особенность, типа предложенного выше удаления дубликатов.
В итоге, если все исправить, то этот код перестанет работать правильно...
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, ilya_ny, Вы писали:
_>>Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться _>>в принципе это логично... M>Это абсолютно не логично, и ни кто, кроме Интербейса, таких вольностей себе не позволяет.
А можно меня тыкнуть в описание SQL92? Мне почему-то помнится, что в стандарте порядок вычисления не определен. А посему — на усмотрение разработчика. И MSSQL IB не указ
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Sinclair, Вы писали:
S>>Здорово, да? M>) Не то слово... M>А интересно, какой-нибудь INSERT INTO table ... SELECT ... FROM Table, в бесконечный цикл это чудо вгонит? M>Или update не шибко не тривиальный?
Скорее всего вгонит. Что написали — то и получите
M>Самое прикольное, что этот баг практически не пофиксишь, поскольку я более чем уверен, что умельцами уже написана куча кода в расчете на эту особенность, типа предложенного выше удаления дубликатов. M>В итоге, если все исправить, то этот код перестанет работать правильно...
В связи с чем исправлять? IB удовлетворяет стандарту SQL92. Где ошибка?
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, ilya_ny, Вы писали:
_>>Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться _>>в принципе это логично... M>Это абсолютно не логично, и ни кто, кроме Интербейса, таких вольностей себе не позволяет.
НАшел:
13.7 <delete statement: searched>
Function
Delete rows of a table.
Format
<delete statement: searched> ::=
DELETE FROM <table name>
[ WHERE <search condition> ]
[skipped]
General Rules
[skipped]
If <search condition> is specified, then it is applied to
each row of T with the <table name> bound to that row, and
all rows for which the result of the <search condition> is
true are marked for deletion.
The <search condition> is effectively evaluated for each row
of T before marking for deletion any row of T.
Each <subquery> in the <search condition> is effectively
executed for each row of T and the results used in the ap-
plication of the <search condition> to the given row of T.
If any executed <subquery> contains an outer reference to a
column of T, the reference is to the value of that column in
the given row of T.
3) If any row that is marked for deletion by the <delete statement:
searched> has been marked for deletion by any <delete statement:
positioned> that identifies some cursor CR that is still open
or updated by any <update statement: positioned> that identifies
some cursor CR that is still open, then a completion condition
is raised: warning-cursor operation conflict.
4) All rows that are marked for deletion are effectively deleted
at the end of the <delete statement: searched> prior to the
checking of any integrity constraint.
5) If no row is deleted, then a completion condition is raised: no
data.
Leveling Rules
1) The following restrictions apply for Intermediate SQL:
a) No leaf generally underlying table of T shall be an under-
lying table of any <query expression> generally contained in
the <search condition>.
Здравствуйте, Romkin, Вы писали:
R>Мне почему-то помнится, что в стандарте порядок вычисления не определен. А посему — на усмотрение разработчика.
Правильно, не определен. Поэтому конечный результат от порядка зависеть не должен, чувствуешь разницу?
А в IB зависит, и это не правильно.
И разработчик тут непричем, в таких вещах полагаться на разрработчика нельзя, это вотчина оптимизатора. А если результат зависит от порядка выполнения, то о сколь-либо эффективном оптимизаторе можно забыть, поскольку в этом случае у сервера практически не остается инструментов для оптимизации, он не может себе позволить сделать эквивалентное преобразование, поскольку в этом случае изменится результат запроса.
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>>Мне почему-то помнится, что в стандарте порядок вычисления не определен. А посему — на усмотрение разработчика. M>Правильно, не определен. Поэтому конечный результат от порядка зависеть не должен, чувствуешь разницу? M>А в IB зависит, и это не правильно. M>И разработчик тут непричем, в таких вещах полагаться на разрработчика нельзя, это вотчина оптимизатора. А если результат зависит от порядка выполнения, то о сколь-либо эффективном оптимизаторе можно забыть, поскольку в этом случае у сервера практически не остается инструментов для оптимизации, он не может себе позволить сделать эквивалентное преобразование, поскольку в этом случае изменится результат запроса.
Я имел в виду разработчика этого самого оптимизатора.
Увы, в стандарте точно указано:
The <search condition> is effectively evaluated for each row
of T before marking for deletion any row of T.
All rows that are marked for deletion are effectively deleted
at the end of the <delete statement: searched> prior to the
checking of any integrity constraint.
Следовательно, IB пролетает Только что проверил на FB1.5 — тожесамо
Правда, у меня такого нет нигде, в таких случаях все идет через where current of
Здравствуйте, Romkin, Вы писали:
R>Скорее всего вгонит. Что написали — то и получите
Это нормально? Нет это не нормально...
Хотя, говорят, в FireBird'е это пофиксили...
R>IB удовлетворяет стандарту SQL92.
В каком месте?
Здравствуйте, Romkin, Вы писали:
R>Я имел в виду разработчика этого самого оптимизатора.
Ну ясен хобот, разработчик оптимизатора в таких условиях нервно курит и рвет остатки волос от отчаянья... Ну или идет писать нормальные оптимизаторы под другие сервера... =)
Понятно, почему оптимизатора в IB практически нет, он лишний раз чихнуть не может...
R>Увы, в стандарте точно указано:<...>
Тут дело даже не в операторе delete, а в том, что результат в принципе не должен зависить от порядка применения операторов.
R> Только что проверил на FB1.5 — тожесамое...
А вот это странно, вроде бы в FB это фиксили?
Мы уже победили, просто это еще не так заметно...
Re[12]: Особенности Interbase
От:
Аноним
Дата:
19.03.04 10:02
Оценка:
Здравствуйте, Merle, Вы писали:
R>> Только что проверил на FB1.5 — тожесамое... M>А вот это странно, вроде бы в FB это фиксили?
Hello, Merle!
M> Это нормально? Нет это не нормально...
Это не так как бы тебе хотелось, но докажи что это не нормально.
M> Хотя, говорят, в FireBird'е это пофиксили...
Мда? Не знал.
А что тут фиксить надо?
Здравствуйте, Arioch, Вы писали:
A>Это не так как бы тебе хотелось, но докажи что это не нормально.
Да при чем тут мое хотение? Это противоречит и стандарту и здравому смыслу. Подобное поведение приводит к зависимости результата от последовательности выполнения операторов, что, в свою очередь, приводит к невозможности написать более-менее толковый оптимизатор.
Это нормально?
M>> Хотя, говорят, в FireBird'е это пофиксили... A>Мда? Не знал.
Нет? Ну тогда это лишний повод не связываться с IB и его клонами...
A>А что тут фиксить надо?
Да не хотите не надо, что я — зверь какой?
Hello, Merle!
M> Это противоречит и стандарту
Цитата под руками есть?
M> и здравому смыслу.
Есть зоть один сервер, где бы ни-че-го не противоречило здравому смыслу?
M> Подобное поведение приводит к зависимости результата от M> последовательности выполнения операторов,
В данном случае, никаих вариантов последовательности нет.
Здравствуйте, Arioch, Вы писали:
A>Hello, Merle!
M>> Это нормально? Нет это не нормально... A>Это не так как бы тебе хотелось, но докажи что это не нормально.
Я уже выше привел выдержки из стандарта. Это действительно не нормально
Это противоречит и стандарту и здравому смыслу. Подобное поведение приводит к зависимости результата от последовательности выполнения операторов, что, в свою очередь, приводит к невозможности написать более-менее толковый оптимизатор.
Почему ты так решил? Оптимизатор нормально уже работает в FB. Кстати, я не думаю, что это противоречит здравому смыслу
M>>> Хотя, говорят, в FireBird'е это пофиксили... A>>Мда? Не знал. M>Нет? Ну тогда это лишний повод не связываться с IB и его клонами...
Здравствуйте, Arioch, Вы писали:
M>> Это противоречит и стандарту A>Цитата под руками есть?
Ну про delete уже приводили, а общий случай искать лень, но это же очевидно.
M>> и здравому смыслу. A>Есть зоть один сервер, где бы ни-че-го не противоречило здравому смыслу?
Ну практически все сервера, за исключением мелких недочетов, здравому смыслу не противоречат. Этот же недочет мелким не назовешь.
A>В данном случае, никаих вариантов последовательности нет.
Во-первых они потенциально возможны, а во вторых, я не считаю нормальной ситуацию, когда простейший self join может положить сервер напрочь.
Здравствуйте, Arioch, Вы писали:
A>Где тут join ??? self join — общий случай, когда оператор/ы замыкает отношение само на себя. Подозреваю, что проблемы могут быть не только с insert'ом
A>И сервер не ляжет, он займет максимум места на таблицу/файл, потом скажет A>облом и rollback.
Ага, а процессор эта операция совсем не грузит? И очередь к диску не выстраивается? И время на откат этой кучи мусора и опять-таки дисковых операций не требуется?
При более-менее серьезной нагрузке такой запрос положит сервер на раз-два-три.
A>Ну не хорошо, но грабли везде есть.
Нифига себе — нехорошо... Это плохо...
Здравствуйте, Romkin, Вы писали:
R>Почему ты так решил?
Я уже написал почему. Первое что делает оптимизатор — это путем перестановок операторов добивается более эффективного получения того же самого результата. А при такой ситуации особо не по переставляешь.
R>Оптимизатор нормально уже работает в FB.
"Не верю" (c)
R>Нет, это повод не писать диких запросов
Да какой он там дикий? Тут как по минному полю — шаг в сторону и все, баста карапузики...
Здравствуйте, Merle, Вы писали:
R>> Оптимизатор нормально уже работает в FB. M> M> "Не верю" (c)
Правильнее будет сказать, что он стал заметно лучше. Если и тут не веришь, вызываю на дуэль
А насчет сабжа — весьма некузяво это, разумеется. Мягко говоря. Самое неприятное, что это не то, чтобы бага, а скорее "as designed"... И безболезненно сменить поведение будет ой как нелегко. Эээххх...
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>>Почему ты так решил? M>Я уже написал почему. Первое что делает оптимизатор — это путем перестановок операторов добивается более эффективного получения того же самого результата. А при такой ситуации особо не по переставляешь.
И что? Я переставляю. Нормально.
R>>Оптимизатор нормально уже работает в FB. M>"Не верю" (c)
Не хочешь — не верь
R>>Нет, это повод не писать диких запросов M>Да какой он там дикий? Тут как по минному полю — шаг в сторону и все, баста карапузики...
Ну-ну. За N лет работы с IB у меня впечатления работы сапером не было. В отличие от MSSQL, кстати, там для меня ужастики были (я посмотрел MSSQL6.5 и офигел в свое время).
Здравствуйте, Romkin, Вы писали:
R>И что? Я переставляю. Нормально.
Хха.. Во-первых у тебя результат запроса будет другой, но, допустим, что ты переставил удачно... Но через полдня статистика поменялась и выгодным стал другой план запроса и, соответственно, порядок выполнения операторов.
Чего делать будешь? Опять менять?
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>>И что? Я переставляю. Нормально. M>Хха.. Во-первых у тебя результат запроса будет другой, но, допустим, что ты переставил удачно... Но через полдня статистика поменялась и выгодным стал другой план запроса и, соответственно, порядок выполнения операторов. M>Чего делать будешь? Опять менять?
Млин, не так переставляю
for select ID
from TEST1
GROUP BY ID
HAVING count(ID) > 1
into :ID
do
delete from TEST1 where ID = :ID;
Здравствуйте, Romkin, Вы писали:
R>Млин, не так переставляю
И так каждый раз? Здесь я говорю уже не о конкретном примере. Оптимизатор в принципе не может свободно менять порядок операторов, потому что это может привести к искажению результата...
То есть в IB, по прежнему, приходится жестко прописывать запросы хинтами, что не есть гуд.
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>>Млин, не так переставляю M>И так каждый раз? Здесь я говорю уже не о конкретном примере. Оптимизатор в принципе не может свободно менять порядок операторов, потому что это может привести к искажению результата... M>То есть в IB, по прежнему, приходится жестко прописывать запросы хинтами, что не есть гуд.
Никаких хинтов Зачем? При таком написании оптимизатор подключит оптимальный индекс в том и другом запросе.
И так каждый раз. Нету у меня в БД вложенных подзапросов и очень мало джойнов. VIEW нет совершенно, вместо них select SP. Так повелось еще с IB 5.6, максимальная скорость и оптимальный план. Дело в том, что в IB получить набор записей из SP — раз плюнуть
Здравствуйте, Romkin, Вы писали:
R> Нету у меня в БД вложенных подзапросов и очень мало джойнов.
Счастливчик..
Довольно большой процент задач можно свести к простым запросам, но как правило, хороший оптимизатор спарвляется с этим эффективнее.
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>> Нету у меня в БД вложенных подзапросов и очень мало джойнов. M>Счастливчик.. M>Довольно большой процент задач можно свести к простым запросам, но как правило, хороший оптимизатор спарвляется с этим эффективнее.
Дык их нет потому, что я их разворачиваю в for select. И получается весьма неплохо.
Например, есть документ DOC, в нем Client_ID со ссылкой на CLIENT(ID, name). Ессно, хочется запрос (допустим):
select DOC.NUM, DOC.Client_ID, CLIENT.name as Client_name
from DOC left join CLIENT on DOC.Client_ID = CLIENT.Client_ID
where DOC.NUM = :FNUM;
Так?
create procedure LIST_DOC (FNUM integer)
returns (NUM integer, Client_ID integer, Client_Name varchar(100))
as
begin
for select NUM, Client_ID
from DOC
where DOC.NUM = :FNUM
into :NUM, :Client_ID
do begin
Client_Name = NULL;
select name from client
where Client_ID = :Client_ID;
suspend;
end
end;
А так? Вызов примитивен: Select * from LIST_DOC(:FNUM), но при наличии многих джойнов (а не одного, как здесь) план будет гораздо эффективнее во втором случае. Соответственно, выигрыш в скорости — в разы.
Так уж устроен оптимизатор в IB, он действительно примитивен. Ждем FB2
Здравствуйте, dimitr, Вы писали:
D>А насчет сабжа — весьма некузяво это, разумеется. Мягко говоря. Самое неприятное, что это не то, чтобы бага, а скорее "as designed"... И безболезненно сменить поведение будет ой как нелегко. Эээххх...
а как насчет маштабируемости? ежели подзапрос "перевыполняется" на "каждом шаге"?
это же пинцет какой-то. и это в простых случаях! а ежели три вложенных друг в друга? ужас!
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Здравствуйте, _MarlboroMan_, Вы писали:
_MM_>Здравствуйте, dimitr, Вы писали:
_MM_>а как насчет маштабируемости? ежели подзапрос "перевыполняется" на "каждом шаге"?
_MM_>это же пинцет какой-то. и это в простых случаях! а ежели три вложенных друг в друга? ужас!
Как правило, вложенный запрос зависит от внешнего Если не зависит — его просто надо вынести в наружный цикл. И получается кузяво
Здравствуйте, Romkin, Вы писали:
R>А так? Вызов примитивен: Select * from LIST_DOC(:FNUM), но при наличии многих джойнов (а не одного, как здесь) план будет гораздо эффективнее во втором случае. Соответственно, выигрыш в скорости — в разы. R>Так уж устроен оптимизатор в IB, он действительно примитивен. Ждем FB2
Пипец... Это покруче хинтов, ты по сути, полностью прописываешь ход выполнения запроса не оставляя серверу ни шанса вмешаться. Дааа....
А ведь встречаются ситуации, когда Hash или Merge join в десятки, если не в сотни раз выгоднее, и фиг ты это дело сэмулируешь на таких циклах. Да банально, оптимальный порядок объединения таблиц может меняться вообще от запроса к запросу...
А ты еще на MS 6.5 жаловался, нет, ребята IB — это для маньяков..
Здравствуйте, Merle, Вы писали:
M>Пипец... Это покруче хинтов, ты по сути, полностью прописываешь ход выполнения запроса не оставляя серверу ни шанса вмешаться. Дааа.... M>А ведь встречаются ситуации, когда Hash или Merge join в десятки, если не в сотни раз выгоднее, и фиг ты это дело сэмулируешь на таких циклах. Да банально, оптимальный порядок объединения таблиц может меняться вообще от запроса к запросу... M>А ты еще на MS 6.5 жаловался, нет, ребята IB — это для маньяков..
Когда join быстрее получается — делаю его. Не догма. Выбирается то, что быстрее.
Здравствуйте, Romkin, Вы писали:
R> Когда join быстрее получается — делаю его. Не догма. Выбирается то, что быстрее.
Дык в том-то и засада, что сейчас быстрее один join, а через полчаса другой... Не на выбираешься.
Привет, Merle!
Вы пишешь 19 марта 2004:
R>> Когда join быстрее получается — делаю его. Не догма. Выбирается то, что быстрее. M> Дык в том-то и засада, что сейчас быстрее один join, а через полчаса другой... Не на выбираешься.
Тут ты не прав. Давайте обсуждать вкусовые качества устриц с теми кто их пробовал ;о)
Здравствуйте, Alex.Che, Вы писали:
AC>Тут ты не прав. Давайте обсуждать вкусовые качества устриц с теми кто их пробовал ;о)
Ты про каких устриц? И в чем я не прав?
Хочешь сказать, что в большинстве систем оптимальный план большинства запросов определяетя на этапе разработки?
Так не бывает.
Здравствуйте, Alex.Che, Вы писали:
AC>Привет, Merle! AC>Вы пишешь 19 марта 2004:
R>>> Когда join быстрее получается — делаю его. Не догма. Выбирается то, что быстрее. M>> Дык в том-то и засада, что сейчас быстрее один join, а через полчаса другой... Не на выбираешься.
AC>Тут ты не прав. Давайте обсуждать вкусовые качества устриц с теми кто их пробовал ;о)
не, ну ты странный... пол-часа назад у меня в таблице ордеров было 100 записей, а щаз стало 10 000. и всё. порядок джоинов совсем другой должен быть. да мало ли как меняется статистика.
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Привет, Merle!
Вы пишешь 19 марта 2004:
AC>> Тут ты не прав. Давайте обсуждать вкусовые качества устриц с теми кто их пробовал ;о) M> Ты про каких устриц? И в чем я не прав? M> Хочешь сказать, что в большинстве систем оптимальный план большинства запросов определяетя на этапе разработки?
Ты не съезжай, не съезжай ;о)
Я про то, что вынесено в subject этой ветки.
Здравствуйте, _MarlboroMan_, Вы писали:
_MM_>Здравствуйте, Alex.Che, Вы писали:
AC>>Привет, Merle! AC>>Вы пишешь 19 марта 2004:
R>>>> Когда join быстрее получается — делаю его. Не догма. Выбирается то, что быстрее. M>>> Дык в том-то и засада, что сейчас быстрее один join, а через полчаса другой... Не на выбираешься.
AC>>Тут ты не прав. Давайте обсуждать вкусовые качества устриц с теми кто их пробовал ;о)
_MM_>не, ну ты странный... пол-часа назад у меня в таблице ордеров было 100 записей, а щаз стало 10 000. и всё. порядок джоинов совсем другой должен быть. да мало ли как меняется статистика.
Хм... И Если в приведенном мной примере есть индекс по DOC.NUM и Client_ID — первичный ключ у CLIENT, то куда что изменится?! Селективность первичного ключа?
Здравствуйте, Romkin, Вы писали:
R>Хм... И Если в приведенном мной примере есть индекс по DOC.NUM и Client_ID — первичный ключ у CLIENT, то куда что изменится?! Селективность первичного ключа?
да нет, я в селекте проверяю овнера для ордера, и еще отдел просматривающего и еще дату создания ордера и еще... короче много всего.
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Здравствуйте, _MarlboroMan_, Вы писали:
_MM_>не, ну ты странный... пол-часа назад у меня в таблице ордеров было 100 записей, а щаз стало 10 000. и всё. порядок джоинов совсем другой должен быть. да мало ли как меняется статистика.
Точнее даже, я что, не знаю примерного соотношения мощностей отношений? Вот еще... Если в одной таблице не более 1000 записей (ну просто не может быть), а остальные растут неограниченно (порядка 100000 записей и более), то вполне можно понять, что выбрать.
А вот если сопоставимо — то да, join. Но разуумненько, благо выбор есть.
Здравствуйте, _MarlboroMan_, Вы писали:
_MM_>Здравствуйте, Romkin, Вы писали:
R>>Хм... И Если в приведенном мной примере есть индекс по DOC.NUM и Client_ID — первичный ключ у CLIENT, то куда что изменится?! Селективность первичного ключа?
_MM_>да нет, я в селекте проверяю овнера для ордера, и еще отдел просматривающего и еще дату создания ордера и еще... короче много всего.
Ну согласись, это уже совершенно другой случай. Однако. Чем рассмотренный в заголовке, и даже чем рассмотренный мной. ТУт думать надо, смотреть, выбирать
Здравствуйте, Romkin, Вы писали:
R>Ну согласись, это уже совершенно другой случай. Однако. Чем рассмотренный в заголовке, и даже чем рассмотренный мной. ТУт думать надо, смотреть, выбирать
в том то и дело, что оптимизатор лучше посмотрит и выберет для каждого отдельного запроса сообразно статистике. а тат мы ему эту возможность в корне отрезаем в одном случае, а в другом имеем шанс нарваться на crash.
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Привет, _MarlboroMan_!
Вы пишешь 19 марта 2004:
R>> Ну согласись, это уже совершенно другой случай. Однако. Чем рассмотренный в заголовке, и даже чем рассмотренный мной. ТУт R>> думать надо, смотреть, выбирать
M> в том то и дело, что оптимизатор лучше посмотрит и выберет для каждого отдельного запроса сообразно статистике. а тат мы M> ему эту возможность в корне отрезаем
Я не знаю, что вы там с этим корнем делаете, но поскольку речь идёт об IB и его особенностях,
то стОит таки эти самые особенности учитывать, а не фантазировать.
В частности, учитывать то, как оптимизатор IB работает со статистикой, и то, когда именно оная
статистика обновляется.
Оптимизатор конечно, слабенький, но чтоб хаять, нужно таки его знать (имхо).
Здравствуйте, Alex.Che, Вы писали:
AC>Оптимизатор конечно, слабенький, но чтоб хаять, нужно таки его знать (имхо).
Не, погоди... Ты внимательно весь топик прочитал?
Про оптимизатор, как таковой, речь не идет. В предлагаемых примерах на него как раз забивают.
Здравствуйте, Alex.Che, Вы писали:
AC>Ты не съезжай, не съезжай ;о)
И в мыслях не было...
AC>Я про то, что вынесено в subject этой ветки.
В subject'е этой ветки — некорректное поведение IB с SELECT'ами и, как следствие — слабость оптимизатора.
Привет, Merle!
Вы пишешь 19 марта 2004:
AC>> Оптимизатор конечно, слабенький, но чтоб хаять, нужно таки его знать (имхо). M> Не, погоди... Ты внимательно весь топик прочитал? M> Про оптимизатор, как таковой, речь не идет. В предлагаемых примерах на него как раз забивают.
Опять стрелки переводишь? ;о)
Мой праведный гнев вызвала фраза господина _MarlboroMan_'а:
=========Beginning of the citation==============
не, ну ты странный... пол-часа назад у меня в таблице ордеров было 100 записей,
а щаз стало 10 000. и всё. порядок джоинов совсем другой должен быть.
да мало ли как меняется статистика.
=========The end of the citation================
Потому как IB, в плане обновления статистики, ведёт себя несколько не так как вы привыкли на MS SQL.
В данном случае, это как раз и есть его особенности.
Здравствуйте, Alex.Che, Вы писали:
AC>Опять стрелки переводишь? ;о)
Нет, это все-таки ты не внимательно читаешь... =)
AC>Потому как IB, в плане обновления статистики, ведёт себя несколько не так как вы привыкли на MS SQL.
В данном случае твой праведный гнев совершенно не по делу, поскольку эта фраза Мальборо относилась к сообщению в котором предлагалось вообще збить на статистику и все делать в ручную.
И Мальборо этой фразой, как раз показывал недостатки такого подхода, тоесть отстаивал ровно твою точку зрения, что даже в IB статистика нужна.
Другое дело, что IB не всегда в полной мере может ей распорядиться, и вот это вот его особенности.
[Sorry, skipped] AC>> Потому как IB, в плане обновления статистики, ведёт себя несколько не так как вы привыкли на MS SQL. M> В данном случае твой праведный гнев совершенно не по делу, поскольку эта фраза Мальборо относилась к сообщению в котором M> предлагалось вообще збить на статистику и все делать в ручную. И Мальборо этой фразой, как раз показывал недостатки такого M> подхода, тоесть отстаивал ровно твою точку зрения, что даже в IB статистика нужна.
Ну, это он пущай сам скажет, чего он имел в виду
M> Другое дело, что IB не всегда в полной мере может ей распорядиться, и вот это вот его особенности.
Опять съехал...
Я про актуализацию статистики, а ты опять "...заунывную песню свою"...
Здравствуйте, Alex.Che, Вы писали:
AC>Ну, это он пущай сам скажет, чего он имел в виду
считай сказал
AC>Опять съехал... AC>Я про актуализацию статистики, а ты опять "...заунывную песню свою"...
а нафига она нужна если у тебя либо руками план строится, либо вероятность крэша?
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Здравствуйте, Alex.Che, Вы писали:
AC>Я про актуализацию статистики, а ты опять "...заунывную песню свою"...
Да при чем тут статистика? Ей никто пользоваться не собирается.
Давай по шагам:
1. У оптимизатора проблемы.
2. Пердлагается жестко задвинуть оптимизатор и подумать за него.
3. Обсуждаются недостатки этого подхода.
4. Тут ты, сосвоей статистикой... Зачем? Если мы пользуемся статистикой, мы скатываемся к случаю (1) — у оптимизатора проблемы. (чтобы понять что такое рекурсия, надо сначала понять, что такое рекурсия)
Нас сейчас не интересует ни статистика, ни способы ее сбора и обработки.
[Sorry, skipped] AC>> Я про актуализацию статистики, а ты опять "...заунывную песню свою"...
M> а нафига она нужна если у тебя либо руками план строится, либо вероятность крэша?
У кого это "у тебя"? Ты мою базу видел, или мои запросы?..
Не нужно эмоциональной пыли
Здравствуйте, Alex.Che, Вы писали:
AC>Опять съехал... AC>Я про актуализацию статистики, а ты опять "...заунывную песню свою"...
я конечно понимаю что есть огромная ниша "примитивных" запросов для которых все наши [рассуждения, замечания, недовольства и т.д.] никакой роли не играют и их вполоне неплохо используют легионы разработчиков и т.д., но что-то более-менее сложное "мутить" с использованием такой субд, к которой у меня есть те самые [рассуждения, замечания, недовольства и т.д.] лично я бы не стал. бо геморрно. не сухо и не комфортно. и никакие прокладки тут не помогут.
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Привет, Merle!
Вы пишешь 19 марта 2004:
AC>> Я про актуализацию статистики, а ты опять "...заунывную песню свою"... M> Да при чем тут статистика? Ей никто пользоваться не собирается.
Это потому что один человек в этой конференции заявил, что он всё планирует руками,
и сразу оба модератора решили, что для IB это есть нормально и все IB-шники так поступают?
Здравствуйте, Alex.Che, Вы писали:
AC>У кого это "у тебя"? Ты мою базу видел, или мои запросы?.. AC>Не нужно эмоциональной пыли
считай, что вместо "у тебя" я написал "у разработчика для/под СУБД interbase"
и "Не нужно эмоциональной пыли" (с)
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Здравствуйте, Alex.Che, Вы писали:
AC>Это потому что один человек в этой конференции заявил, что он всё планирует руками, AC>и сразу оба модератора решили, что для IB это есть нормально и все IB-шники так поступают?
Эээээ... спокуха на лице Мы обсуждали конкретную ситуацию, почему все IB'шники решили, что мы с ними не дружим..
Привет, _MarlboroMan_!
Вы пишешь 19 марта 2004:
AC>> Опять съехал... AC>> Я про актуализацию статистики, а ты опять "...заунывную песню свою"...
M> я конечно понимаю что есть огромная ниша "примитивных" запросов для которых все наши M> [рассуждения, замечания, недовольства и т.д.] никакой роли не играют и их вполоне неплохо M> используют легионы разработчиков и т.д., но что-то более-менее сложное "мутить" с использованием такой субд, M> к которой у меня есть те самые [рассуждения, замечания, недовольства и т.д.] лично я бы не стал. бо геморрно.
Ты лично на ней пытался что-либо "сурьёзное" сделать?
Нет? Ну и нефик тут пальцы веером крутить. Фи.
Здравствуйте, Alex.Che, Вы писали:
AC>Привет, Merle! AC>Вы пишешь 19 марта 2004:
AC>>> Я про актуализацию статистики, а ты опять "...заунывную песню свою"... M>> Да при чем тут статистика? Ей никто пользоваться не собирается.
AC>Это потому что один человек в этой конференции заявил, что он всё планирует руками, AC>и сразу оба модератора решили, что для IB это есть нормально и все IB-шники так поступают?
неа. не так. один человек заявил что в IB что делается так-то. после чего модераторы и уважаемые участники форума сказали: ну это косяк. и даже не косяк а КОСЯК и так низзя — бо может стать мучительно больно "за бесцельно прожитые годы"".
на что было сказано: "дык если так, то можно [вот так]", на что последовал ответ: так тоже плохо бо [вот есть такая ситуация]" и вывод: Re[35]: Особенности Interbase
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Привет, Merle!
Вы пишешь 19 марта 2004:
AC>> Это потому что один человек в этой конференции заявил, что он всё планирует руками, AC>> и сразу оба модератора решили, что для IB это есть нормально и все IB-шники так поступают? M> Эээээ... спокуха на лице Мы обсуждали конкретную ситуацию, почему все IB'шники решили, что мы с ними не дружим..
Здравствуйте, Alex.Che, Вы писали:
AC>Ты лично на ней пытался что-либо "сурьёзное" сделать? AC>Нет? Ну и нефик тут пальцы веером крутить. Фи.
да вы батенька демагог приотменнейший. конструктив будет или всё?
... << RSDN@Home 1.1.3 beta 1 >>
— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
[Sorry, skipped] AC>> Это потому что один человек в этой конференции заявил, что он всё планирует руками, AC>> и сразу оба модератора решили, что для IB это есть нормально и все IB-шники так поступают?
M> неа. не так. один человек заявил что в IB что делается так-то. после чего модераторы и уважаемые участники форума сказали: ну M> это косяк. и даже не косяк а КОСЯК и так низзя — бо может стать мучительно больно "за бесцельно прожитые годы"".
О том, что косяк, подтвердил и один из ведущих девелоперов FireBird. Никто и не спорит.
А вот то что можно закладываться на это как на фичу — на совести того, кто это сказал.
И никто из специалистов это не рекомендует к использованию в данном конкретном случае.
Например: http://www.ibase.ru/devinfo/deldupes.htm
Привет, _MarlboroMan_!
Вы пишешь 19 марта 2004:
AC>> Ты лично на ней пытался что-либо "сурьёзное" сделать? AC>> Нет? Ну и нефик тут пальцы веером крутить. Фи.
M> да вы батенька демагог приотменнейший. конструктив будет или всё?
И я же ещё и крайний?!
Вспоминается: «Я Пастернака не читал, но осуждаю!».
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Alex.Che, Вы писали:
AC>>Я про актуализацию статистики, а ты опять "...заунывную песню свою"... M>Да при чем тут статистика? Ей никто пользоваться не собирается. M>Давай по шагам: M>1. У оптимизатора проблемы. M>2. Пердлагается жестко задвинуть оптимизатор и подумать за него. M>3. Обсуждаются недостатки этого подхода. M>4. Тут ты, сосвоей статистикой... Зачем? Если мы пользуемся статистикой, мы скатываемся к случаю (1) — у оптимизатора проблемы. (чтобы понять что такое рекурсия, надо сначала понять, что такое рекурсия)
M>Нас сейчас не интересует ни статистика, ни способы ее сбора и обработки.
Тц! Я предложил всего лишь способ выполнить запрос так, чтобы получить требуемые результаты. Отнюдь не секрет, что оптимизатор IB не так хорош, как у больших серверов.
Но я не предлагал писать только такие запросы! Или так, или так — не подходит. И так, и иначе — гораздо лучше.
Вы думаете, я не смотрю на план и статистику? Вы ошибаетесь. Смотрю. И выбираю тот способ, который быстрее и удобнее. Но вместе с тем я также уверен, что вынос подзапроса, параметры которого не зависят от внешнего — самый быстрый способ получить требуемый результат. Хотя бы потому, что подзапрос выполнится один раз. Что и было приведено.
В других случаях — по ситуации. Обычно пробуется 2-3 варианта запроса, и выбирается наиболее быстрый. И не надо говорить, что ситуация может резко изменится — выбор идет на тестовой базе, с реальными данными. Дело в том, что я обычно сталкиваюсь, можно сказать, с тремя типами таблиц БД: Первый тип — таблица с небольшим количеством строк, причем их количество практически не меняется, оно фиксировано и примерно известно. Второй тип — таблица со средним количеством строк, которая растет средним темпом. Третий тип — массивная таблица, с приростом в разы большим, чем во втором случае.
В случае соединений разных типов таблиц я вполне могу прикинуть, как лучше написать запрос. А вот при работе с одинаковыми мощностями таблиц — надо смотреть и на план, и на статистику.
Здравствуйте, Merle, Вы писали:
M>Здравствуйте, Romkin, Вы писали:
R>>Скорее всего вгонит. Что написали — то и получите M>Это нормально? Нет это не нормально... M>Хотя, говорят, в FireBird'е это пофиксили...
R>>IB удовлетворяет стандарту SQL92. M>В каком месте?
Можно сделать select from ... order by id desc
тогда не вгонит
Re[7]: Особенности Interbase
От:
Аноним
Дата:
29.09.05 08:35
Оценка:
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, <Аноним>, Вы писали: А>>На каком сервере ты это пробовал или так просто чисто интуитивно написал в Interbase удаляет все кроме одной это связано с тем, что Вложенный селект выполняеться заново после каждого делита — соответственно одна запись останеться S>Охренеть! Специально поставил Interbase 6.5 для проверки. Я и раньше знал, что Interbase — редчайший отстой, но чтоб настолько жидко... S>тест 1: S>
S>create table test(id int, val char(5));
S>insert into test values(1, 'red');
S>insert into test values(2, 'green');
S>insert into test values(3, 'blue');
S>insert into test values(2, 'green');*/
S>delete from test
S> where test.ID in (select id from test GROUP BY id HAVING count(id)>1);
S>select * from test;
S>
S>Результат: S>
S>id value
S>-- -----
S>01 red
S>02 green
S>03 blue
S>
S>Давайте убедимся, что это — страшный косяк. Попробуем вычислить предикат в условии Delete вручную и скормить уже его: S>
S>create table test(id int, val char(5));
S>insert into test values(1, 'red');
S>insert into test values(2, 'green');
S>insert into test values(3, 'blue');
S>insert into test values(2, 'green');*/
S>/* А вот так можно убедиться в том, что в in стоит именно эта коллекция:*/
S>select id from test GROUP BY id HAVING count(id)>1;
S>delete from test
S> where test.ID in(2);
S>select * from test;
S>
S>Результат: S>
S>id value
S>-- -----
S>01 red
S>03 blue
S>
S>Здорово, да? То есть у нас результат запроса зависит от порядка вычисления аргументов. Мы вроде как сделали эквивалентную замену (а ведь SQL — это функциональный язык), а результат изменился. Другая особенность в том, что если бы у нас записи с ID = 2 различались в поле val, то результат запроса вообще получается неопределенным. S>В общем, ребята, Interbase — не RDBMS. Нельзя ее применять. Самые простые и очевидные вещи сделаны там через ухо.
1. Попробуйте сделать то-же на Yaffil ... упс — ошибка (ИМХО, более честное поведение);
2. SQL его расширения не есть одно и то-же.
3. Ну и пусть не RDBMS — покажите мне тогда хоть одну и я раскопаю на нее не-RDBMS-овское поведение. А IB, особенно доделанный — это гениальная весч — не каждый движок БД может поместиться ... на 1 дискету и при этом заамечательно обрабатывать OLTP и OLAP запросы (конечно заранее оттюненые) в организации с 200 постояно работающих пользователей, сам работая на целерончике. Настраивая в той-же организации ORACLE на 200 килаграмовом риске ... ну в общем вспоминаешь про IB/Yaffil, не замечая особой разницы в производительности. Ручки и опыт никакая супер-пупер РСУБД не заменит;
4. Да, оракла, к примеру — тоже не RDBMS, если по класике походить :-D.
Здравствуйте, <Аноним>, Вы писали:
А>1. Попробуйте сделать то-же на Yaffil ... упс — ошибка (ИМХО, более честное поведение);
С какого это перепугу ошибка при выполнении совершенно невинного запроса называется честным поведением? Это баг! Поведение интербейза можно списать как фичу А>2. SQL его расширения не есть одно и то-же.
Прошу прощения, что именно здесь расширение? А>3. Ну и пусть не RDBMS — покажите мне тогда хоть одну и я раскопаю на нее не-RDBMS-овское поведение.
См. tpc.org. Там А>А IB, особенно доделанный
Вручную? А>- это гениальная весч — не каждый движок БД может поместиться ... на 1 дискету и при этом заамечательно обрабатывать OLTP и OLAP запросы (конечно заранее оттюненые) в организации с 200 постояно работающих пользователей, сам работая на целерончике.
Видишь ли, с моей точки зрения от РСУБД в первую очередь требуется корректность, во вторую устойчивость, а уже в третью — малое ресурсопотребление. Для несчастных 200 сотрудников, работающих с MSSQL, не потребуется двухсот килограммов риска. Пара гигов памяти и рейд. Про размер инсталляции и говорить нечего — один гиг места на винте вообше ничего не стоит. Если, конечно, эту СУБД не надо дважды в неделю переставлять для стабильной работы
Потери от неверной работы SQL запросов могут стоить на порядок больше такой железяки. Даже затраты на оплату программерских усилий по обходу граблей стоят больше. Нет, я верю в то, что бывают такие организации, в которых и программер работает за 2 МРОТ, и железяку дали шефы после списания, и убыток от простоя исчисляется копейками... Но надо четко понимать границы, за пределами которых эти преимущества теряются. А> Настраивая в той-же организации ORACLE на 200 килаграмовом риске ... ну в общем вспоминаешь про IB/Yaffil, не замечая особой разницы в производительности. Ручки и опыт никакая супер-пупер РСУБД не заменит;
С этим никто не спорит. Но раскладывать грабли посреди ровна поля совершенно незачем.
З.Ы. У нас тут целое поколение народу воспитано в духе блокадного ленинграда. Ну там типа "о-о, этот компонент стоит 200 баксов — давайте лучше напишем свой!" (при зарплате программера в 600 баксов и примерно полугоде времени на разработку). Или там "о-о, пусть этот мэйл сервер глючит и админ каждый раз его настраивает по три ночи, но он жужжит на 486DX266". Надо отучаться от этой позиции. Самое дорогое — это время админа (потому что оно тратится все время эксплуатации). Второе по стоимости — разработчика. Третье — лицензии на софт. А ценой железа можно пренебречь в большинстве случаев.
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Привет, Sinclair!
Вы пишешь 29 сентября 2005:
А>> 1. Попробуйте сделать то-же на Yaffil ... упс — ошибка (ИМХО, более честное поведение); S> С какого это перепугу ошибка при выполнении совершенно невинного запроса называется честным поведением?
Шо, опять?! 8-o
Какой чмудила опять поднял топик годичной давности?
--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[9]: Особенности Interbase
От:
Аноним
Дата:
29.09.05 18:23
Оценка:
А>>1. Попробуйте сделать то-же на Yaffil ... упс — ошибка (ИМХО, более честное поведение); S>С какого это перепугу ошибка при выполнении совершенно невинного запроса называется честным поведением? Это баг!
вы не правы, баг это когда в документации одно а работает по другому. а тут все задокументировано, так что тут все честно — фича.
Здравствуйте, Аноним, Вы писали:
А>Ну вообще то можно и без временной таблицы. А>В интербайсе прокатывает вот такой запрос, который удалит все записи кроме одной с повторяющимся id.
А>
А>delete from Table1
А>where Table1.ID in (select id from Table1 GROUP BY id HAVING count(id)>1)
А>
Вот ещё прикол из той же серии
CREATE TABLE T1 (
A INTEGER,
B INTEGER)
insert into t1 (a,b) values (0,0)
update t1 set a=1, b=a
DS>delete from test
DS> where test.ID = (select id from test GROUP BY id HAVING count(id)>1);
DS>
DS>Приведет к удалению всех id=2
А вот этот запрос вообще должен выдать ошибку. Т.к. идет сравнение значения поля с множеством, а не единичным значением.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
R>А так? Вызов примитивен: Select * from LIST_DOC(:FNUM), но при наличии многих джойнов (а не одного, как здесь) план будет гораздо эффективнее во втором случае. Соответственно, выигрыш в скорости — в разы.
Вообще-то не должно быть. Очень давно видел IB, но законы оптимизации и в Африке законы оптимизации. В данном случае ты получил nested запросы в стиле SystemR. То есть при 1000 строк ты получишь 1000 запросов. Это не совсем гуд, и не сильно оптимально. Если оптимизатор не настолько умный сделать запрос как ему надо(теоретически на таком запросе это возможно) а не как вы написали, вы получите большую неоптимальность. Наиболее оптимальным для такого запроса(если это больше 10 строк) будет именно join.