Конференция "Базы" » Как составить запрос к базе [D7, FB 2]
 
  • OtherSie (23.04.09 22:29) [0]
    Есть 2 таблицы. 1-я - справочник. Содержит в себе список работников и первичный ключ. Вторая - список заказов с прикреплёнными к ним работниками. Содержит 4 поля - внешние ключи - ссылки на первичный ключ первой таблицы и 5-е поле - первичный ключ заказов.

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

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

    Можно ли как-то выполнить задачу одним запросом? Спасибо.
  • sniknik © (23.04.09 23:06) [1]
    > Как сделать с хранимой процедурой с четырьмя подзапросами - знаю.
    процедура и 4-ре подзапроса для объединения 2-х таблиц? мощно! внишаит!...

    хочу знать способ. заинтриговал чертяка. а то одним запросом это как то банально и мелко...
  • turbouser © (23.04.09 23:13) [2]

    > sniknik ©   (23.04.09 23:06) [1]

    А то!  Хочу энто видеть !
  • AndreyV © (23.04.09 23:25) [3]
    > [1] sniknik ©   (23.04.09 23:06)
    > хочу знать способ. заинтриговал чертяка. а то одним запросом
    > это как то банально и мелко...

    Бартер?
  • OtherSie (23.04.09 23:45) [4]
    Как-то так:



    create procedure NEW_PROCEDURE (
       TEST_UID integer)
    returns (
       FIO1 char(10),
       FIO2 char(10),
       FIO3 char(10),
       FIO4 char(10))
    as
    begin
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST1
     into :FIO1;
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST2
     into :FIO2;
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST3
     into :FIO3;
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST4
     into :FIO4;
     suspend;
    end

    select * from NEW_PROCEDURE(1)




    Возвращает то, что мне нужно.
  • OtherSie (23.04.09 23:47) [5]
    Можно ли как-то компактнее сделать?
  • sniknik © (24.04.09 00:23) [6]
    т.е. тебе нужно вот это
    select VOC_CONTANT
    from VOCAB, TEST
    where TEST.TEST_UID = 1 and
            (VOCAB.VOC_UID = TEST.TEST1 or
             VOCAB.VOC_UID = TEST.TEST2 or
             VOCAB.VOC_UID = TEST.TEST3 or
             VOCAB.VOC_UID = TEST.TEST4)
    должен выдать список из 4х полей.
  • sniknik © (24.04.09 00:28) [7]
    но вообще, так не делается, соединяют обычно по одному полю, потому как располагают данные в "высоту" таблицы, а не "ширину" тогда и количество этих данных не будет ограничено 4-мя... да и работать удобнее.
  • OtherSie (24.04.09 00:50) [8]

    > т.е. тебе нужно вот это select VOC_CONTANT



    > должен выдать список из 4х полей.


    Запрос выдаст только одно поле. И 4 условия лишние.


    > но вообще, так не делается, соединяют обычно по одному полю, потому как располагают данные в "высоту" таблицы, а не "ширину" тогда и количество этих данных не будет ограничено 4-мя... да и работать удобнее.


    Если бы удалось выполнить задачу одним запросом - можно было бы отдавать в качестве результата множество записей. Сейчас BETWEEN никак не напишешь, конечно.

    Как вообще делается я знаю. Можно было бы предложить сделать четыре справочника вместо одного. Тогда, конечно, никаких проблем бы не было. Но, дело в том, что одни и те же люди могут входить в разные справочники одновременно (поля TEST1 - TEST4 - это, как я поняли из задания, специальности, необходимые для выполнения задания. они у разных людей могут пересекаться). Поэтому добавление еще трёх справочников приведёт к явной денормальзации базы.
  • OtherSie (24.04.09 00:52) [9]

    > апрос выдаст только одно поле. И 4 условия лишние.


    Сорри, проглючило :)  or не увидел. Буду тестить. Возможно - самое то...
  • Игорь Шевченко © (24.04.09 00:54) [10]

    > (поля TEST1 - TEST4 - это, как я поняли из задания, специальности,
    >  необходимые для выполнения задания. они у разных людей
    > могут пересекаться).


    такой глупый вопрос - а если для выполнения задания потребуется, не дай Аллах, пять специальностей ?

    Вроде как примеров с Job и Skill в любом учебнике по SQL навалом - бери да переписывай любой.
  • OtherSie (24.04.09 00:56) [11]
    Ыыыы.... Не то. Таки да - вернулось же много записей с одним полем. И Between-то работает, но не так, как нужно. ХП то как раз возвращает одну запись с четырьмя полями... Но - слишком сложно и только для одного uid'а...
  • OtherSie (24.04.09 01:02) [12]

    > такой глупый вопрос - а если для выполнения задания потребуется,
    >  не дай Аллах, пять специальностей ?


    Ну и хорошо - добавят еще одно поле (допустим - TEST5), в джобы - нужных людей, у которых есть нужный скилл.


    > Вроде как примеров с Job и Skill в любом учебнике по SQL
    > навалом - бери да переписывай любой.


    Порылся - сходу не нашел. Самому как-то такие задачи не попадались ранее.
  • OtherSie (24.04.09 01:43) [13]
    Нашел таки :)


     select TABL1.VOC_CONTANT, TABL2.VOC_CONTANT, TABL3.VOC_CONTANT, TABL4.VOC_CONTANT
     from VOCAB TABL1, VOCAB TABL2, VOCAB TABL3, VOCAB TABL4, TEST
     where TEST.TEST_UID between 1 and 2 and
           TABL1.VOC_UID = TEST.TEST1 and
           TABL2.VOC_UID = TEST.TEST2 and
           TABL3.VOC_UID = TEST.TEST3 and
           TABL4.VOC_UID = TEST.TEST4




    Не видел раньше алиасов у таблиц :)
  • sniknik © (24.04.09 01:56) [14]
    > Ну и хорошо - добавят еще одно поле (допустим - TEST5), в джобы - нужных людей, у которых есть нужный скилл.
    может сразу тогда этим людям дать программу писать? которые будут твое творение править. у них наверняка лучше получится (лень заставит. как пару раз что нибудь вылезет на поправку когда уже все, что делалось забыл, так сразу научатся головой работать а не руками).

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

    например простая накладная - справочник товаров + справочник документов, отбрасываем разные отвлекающие поля вроде типа накладной, цен товаров для записей, и т.д. оставляем только названия товаров и id для связей как у тебя.
    остается - поле  с номером накладной, и поле связи по id со справочником товаров. в "высоту" прошу заметить, никому в голову не приходит для каждой накладной, полей в "ширину" добавлять, если вдруг товаров больше пришло. и все. по этим двум полям все находится, все записи накладной, по ее номеру, все названия товаров из присоединенного по полю связи справочника. и все в "высоту". так удобнее.
    не, конечно и там среди бухгалтеров попадаются отщепенцы, придумали такую вещь как шахматка... но и ее делают. чаще всего "поворачивая"  полученный результат на клиенте, делая из "высоты" "ширину". можно и на сервере, легко могу сделать на access или mssql  но на FB боюсь их синтаксис не пройдет, даже не пытаться не стоит (а трудов чтобы разбираться задача не стоит. глупая логика).
  • Германн © (24.04.09 02:04) [15]

    > sniknik ©   (24.04.09 01:56) [14]

    Количество двойных кавычек превысило все разумные пределы.
    :)
  • sniknik © (24.04.09 02:06) [16]
    > Нашел таки :)
    даже не написал на нашел? докатились.

    тогда понятно почему запрос "кривоват" - по логике данного запроса данные во всех  полях связей обязательны, к тому же по строгому соответствию, получается можно объединить народ по четверкам и оставить одно поле... будет то же самое.
  • OtherSie (24.04.09 02:56) [17]

    > например простая накладная - справочник товаров + справочник
    > документов, отбрасываем разные отвлекающие поля вроде типа
    > накладной, цен товаров для записей, и т.д. оставляем только
    > названия товаров и id для связей как у тебя.остается - поле
    >  с номером накладной, и поле связи по id со справочником
    > товаров. в "высоту" прошу заметить, никому в голову не приходит
    > для каждой накладной, полей в "ширину" добавлять, если вдруг
    > товаров больше пришло. и все. по этим двум полям все находится,
    >  все записи накладной, по ее номеру, все названия товаров
    > из присоединенного по полю связи справочника. и все в "высоту".
    >  так удобнее.не, конечно и там среди бухгалтеров попадаются
    > отщепенцы, придумали такую вещь как шахматка... но и ее
    > делают. чаще всего "поворачивая"  полученный результат на
    > клиенте, делая из "высоты" "ширину". можно и на сервере,
    >  легко могу сделать на access или mssql  но на FB боюсь
    > их синтаксис не пройдет, даже не пытаться не стоит (а трудов
    > чтобы разбираться задача не стоит. глупая логика).


    Что то ты в дебри полез. Было достаточно сказать, что у таблиц могут быть псевдонимы.


    > даже не написал на нашел?


    Не уверен, что верно понял сказанное. Имелось в виду, что нашел, что у таблиц могут быть алиасы. Хорошая фича.


    > данные во всех  полях связей обязательны,


    Без проблем. Делаем дефолтное значение 0 у таблицы джобов, а нулевому юиду ставим в соответствие что-нибудь типа 'не назначено'.
  • AndreyV © (24.04.09 07:47) [18]
    > [17] OtherSie   (24.04.09 02:56)
    > Что то ты в дебри полез. Было достаточно сказать, что у
    > таблиц могут быть псевдонимы.

    И это всё, что ты увидел в ответе, хотя об этом в нём не говорилось.

    Экселем мыслим.
  • MsGuns © (24.04.09 09:15) [19]
    >Имелось в виду, что нашел, что у таблиц могут быть алиасы. Хорошая фича.

    Как много нам открытий чудных
    Готовит просвещенья дух
    И опыт, сын ошибок трудных,
    И гений, парадоксов друг
     :))
  • Виталий Панасенко (24.04.09 09:56) [20]
    (с) "Очевидное-невероятное"...
  • Виталий Панасенко (24.04.09 09:56) [21]
    шЮтка, конечно А.С.Пушкин.:-)
  • ANB (24.04.09 11:06) [22]
    А потом заказчики удивляются, когда профи, которого просят "чуток доделать уже почти готовую" систему, требует денег за написание новой.
    Дамс.
  • sniknik © (24.04.09 11:08) [23]
    > Имелось в виду, что нашел, что у таблиц могут быть алиасы. Хорошая фича.
    кто ж знал, что ты не знаешь про псевдонимы, про которые пишут на 15-20 й странице любого учебника по sql. и проблему ты видишь только в этом...
    я вот вижу у тебя проблему в нежелании работать со списками, непонимании логики баз. а вовсе не в алиасах.

    кстати, у твоего подхода есть минус, кроме того что там полей не напасешься, ну вот представь, что после будет например 200 человек... 200 полей, и 200 объединений таблицы самой с собой, вместо одно... это хороший способ поставить "на колени" любой sql сервер. даже четыре могут тормозить при определенных условиях. (размер таблиц/отсутствие или невозможность использование индексов)
    вот запиши объединение в явном виде, с помощью join-ов сразу поймешь что имеется в виду. (join-ы это тоже хорошая фича, про которую ты наверное не знаешь, и рекомендуемая к использованию т.к. она ближе к тому как работает sql сервер, больше способствует пониманию, чем неявные объединения)
  • ANB (24.04.09 12:07) [24]

    > (join-ы это тоже хорошая фича, про которую ты наверное не
    > знаешь, и рекомендуемая к использованию т.к. она ближе к
    > тому как работает sql сервер, больше способствует пониманию,
    >  чем неявные объединения)

    Зато с ними тяжелее оптимизить запросы.
  • OtherSie (24.04.09 12:15) [25]

    > И это всё, что ты увидел в ответе, хотя об этом в нём не
    > говорилось.


    Я собственно это и говорил - что алисов не увидел - сам нашел.


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


    Век живи, век учичись, всё равно дураком помрёшь. Базы я знаю плохо - с этим спорить не буду.

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

    Вроде бы никакой крамолы. Во всяком случае, пока...

    200, как и 1000 человек, думаю, никак не повлияют на скорость. 200 джобов, думаю, там не будет никогда. Далее, в случае необходимости, будем оптимизировать базу. Пока ограничимся имеющимся запросом.

    Всем спасибо за ответы.
  • sniknik © (24.04.09 12:35) [26]
    > Зато с ними тяжелее оптимизить запросы.
    дело привычки. тем более когда понимаешь их логику то оптимизировать уже не приходится, сразу пишешь оптимально. а вот в неявных черт ногу сломит, а иногда и sql ый парсер понимает их по разному.

    > Вроде бы никакой крамолы нет.
    4 объединения в любом случае, даже самом оптимистичном, в 4 раз медленнее чем одно. при том же результате, только в непривычном для тебя виде.

    > Далее, в случае необходимости, будем оптимизировать базу.
    не получится. далее тебе ее придется переделывать с 0.

    > Пока ограничимся имеющимся запросом.
    вольному воля.
  • MsGuns © (25.04.09 14:57) [27]
    Сникника пора судить за растрату бисерного фонда :)
  • OtherSie (25.04.09 16:44) [28]
    Сниксника пора судить за стрельбу из пушек по воробьям. Не каждая задача требует абсолютной оптимизации.
  • OtherSie (25.04.09 16:47) [29]
    Особенно когда эта оптимизация утяжеляет решение в разы...
  • OtherSie (25.04.09 16:47) [30]
    Не давая никакого практического выигрыша.
  • AndreyV © (25.04.09 17:13) [31]
    > [28] OtherSie   (25.04.09 16:44)

    Ни хочешь слушать советы - твоё право. Но зачем тогда спрашивал, напрягал людей, заметь - бесплатно?
  • OtherSie (25.04.09 17:16) [32]
    Удалено модератором
  • Удалено модератором
  • ANB (27.04.09 10:08) [34]

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

    явными хорошо, если ты уже знаешь оптимальный план.

    А вот если ты его подбираешь, то частенько вылезает необходимость поменять порядок обхода таблиц. С явными джойнами надо запрос посильнее править.
    Да и букав писать больше.
    У явных джойнов мне нравятся 2 вещи :
    1) Больше вариантов объединения (правда "лишние" варианты весьма экзотические и фулл оутер я всего раз в жизни применял на практике).
    2) Труднее забыть про связки и нарваться на картезиан.
  • sniknik © (27.04.09 10:25) [35]
    > С явными джойнами надо запрос посильнее править.
    > Да и букав писать больше.
    скопипастить 40 символов намного труднее чем 10?

    > 1) Больше вариантов объединения
    ?
    вообще то от синтаксиса конкретного sql сервера зависит, например когда то в первисиве не было синтаксиса явных объединений, но никаких ограничений на их варианты не было, лефт джойн делался += , райт =+ , полное объединение * (или *= с любой стороны, не помню).

    дело вовсе не в вариантах, дело в том что ты пишешь так как это понимает sql сервер, т.е. вы говорите на одном языке. это способствует пониманию.
    с неявными, могут написать и даже не понять что сделали объединение... ни о каком понимании и речи нет.
  • Anatoly Podgoretsky © (27.04.09 11:53) [36]
    > sniknik  (27.04.2009 10:25:35)  [35]

    Что там первисив, в Оракле не было.
  • Игорь Шевченко © (27.04.09 12:02) [37]
    А я до сих пор в оракле (+) пишу - оно как-то понятнее и серверу и мне и моим коллегам
  • ANB (27.04.09 13:55) [38]

    > А я до сих пор в оракле (+) пишу - оно как-то понятнее и
    > серверу и мне и моим коллегам

    Вот и я о том же.


    > скопипастить 40 символов намного труднее чем 10?

    Если у меня хинт ordered и я начинаю играть порядком обхода, то при неявном объединении мне надо будет только поменять местами таблицы во фроме (вырезать+вставить). А при явном - переделывать текст запроса.

    А пониманию больше способствует аккуратное форматирование запросов. Потому как кашу из явных джойнов тоже задерешься разгребать.
  • Кщд (27.04.09 14:53) [39]
    >Игорь Шевченко ©   (27.04.09 12:02) [37]
    >А я до сих пор в оракле (+) пишу - оно как-то понятнее и серверу и мне и моим коллегам
    так, вообще говоря, (+) не эквивалентен left/right outer join
    да и (+)-синтаксис при необходимости full outer join не слишком спасает)
  • Кщд (27.04.09 14:55) [40]
    >ANB   (27.04.09 13:55) [38]
    >Если у меня хинт ordered и я начинаю играть порядком обхода, то при >неявном объединении мне надо будет только поменять местами >таблицы во фроме (вырезать+вставить). А при явном - переделывать >текст запроса.
    а потом, например, dba врубает plan stability, и вся система идет под откос
    хинты - это зло, зло и зло)
  • Игорь Шевченко © (27.04.09 15:01) [41]
    Кщд   (27.04.09 14:53) [39]


    > так, вообще говоря, (+) не эквивалентен left/right outer
    > join


    "Три следующих запроса, в первом из которых используется старый синтаксис, семантически одинаковы:

    SELECT c.course_name, c.period,
     e.student_name
    FROM course c, enrollment e
        WHERE c.course_name = e.course_name(+)

            AND c.period = e.period(+);

    SELECT c.course_name, c.period,
     e.student_name
    FROM course c LEFT OUTER JOIN enrollment e
        ON c.course_name = e.course_name
           AND c.period = e.period;

    SELECT c.course_name, c.period,
     e.student_name
    FROM enrollment e RIGHT OUTER JOIN course c
        ON c.course_name = e.course_name
           AND c.period = e.period;
    "

    http://www.oracle.com/global/ru/oramag/march2002/dev_ansi.html


    > да и (+)-синтаксис при необходимости full outer join не
    > слишком спасает)


    не спасает. Когда требуется full outer join ставится full outer join. Беда только в том, что редко требуется :)
  • Игорь Шевченко © (27.04.09 15:02) [42]

    > хинты - это зло, зло и зло


    Воистину
  • ANB (28.04.09 09:27) [43]

    > full outer join

    Сколько раз в жизни вы им пользовались ?
  • ANB (28.04.09 09:31) [44]

    > хинты - это зло, зло и зло
    >
    >
    > Воистину

    Ну ну. К сожалению, без них частенько никак.
    А если админ попытается угробить работающую систему - так у нас их много.
    Будет новый главный админ, всего то и делов. :)
  • Игорь Шевченко © (28.04.09 15:45) [45]

    > К сожалению, без них частенько никак


    Кривое не может сделаться прямым
  • ANB (29.04.09 10:11) [46]

    > Кривое не может сделаться прямым

    1) Ради одного отчета никто не будет переделывать БД
    2) Даже если структуру БД сделать идеальной, то конвертить туда данные просто нереально.
    3) Все равно придется применять хинты в особо сложных случаях - хэш джойн, распараллеливание запросов. Оптимизатор не идеален.
  • Игорь Шевченко © (29.04.09 10:56) [47]
    ANB   (29.04.09 10:11) [46]

    Ты пойми простую вещь - я не настаиваю на том, чтобы лично ты прекратил пользоваться хинтами, я высказываю свое мнение относительно целесообразности использование костылей при ходьбе вообще.
  • ANB (29.04.09 14:55) [48]

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

    Если оптимизатор сразу дает примерно правильный план - я и не хинтую.
  • Кщд (29.04.09 14:56) [49]
    >Игорь Шевченко ©   (27.04.09 15:01) [41]
    >"Три следующих запроса, в первом из которых используется старый >синтаксис, семантически одинаковы:
    говорил о случаях, когда не одинаковы)
    например,

    select t.*, t2.*
    from tmp t, tmp2 t2
    where t.id = t2.id(+)
         or t.id2 = t2.id2(+)
         
    select t.*, t2.*
    from tmp t
          left join tmp2 t2
            on t.id = t2.id
               or t.id2 = t2.id2

  • Кщд (29.04.09 14:58) [50]
    >ANB   (29.04.09 14:55) [48]
    >Если оптимизатор сразу дает примерно правильный план - я и не хинтую.
    каким образом смотрите план?
  • Anatoly Podgoretsky © (29.04.09 16:16) [51]
    > ANB  (29.04.2009 14:55:48)  [48]

    А если не сразу, а потом, и при этом для обеих случаев, кроме того как выяснили мешает независимому администрированию.
  • Игорь Шевченко © (29.04.09 19:17) [52]
    Кщд   (29.04.09 14:56) [49]

    А планы в студию для обоих вариантов не затруднит ?
  • Кщд (30.04.09 09:17) [53]
    >Игорь Шевченко ©   (29.04.09 19:17) [52]
    затруднит)

    SQL> select t.*, t2.*
     2  from tmp t, tmp2 t2
     3  where t.id = t2.id(+)
     4       or t.id2 = t2.id2(+)
     5  ;

    ORA-01719: оператор внешнего соединения (+) не разрешен в операндах OR или IN


    собственно, об этом и говорил

    или ещё пример:
    как переписать на (+)-синтаксисе такой запрос

    select t.*, t2.*
    from tmp t
         left join tmp2 t2
           on t.id = t2.id
              and t.id2 = 2

  • Игорь Шевченко © (30.04.09 14:06) [54]

    > ORA-01719: оператор внешнего соединения (+) не разрешен
    > в операндах OR или IN


    Уел :)

    Вот что странно - за долгую и многотрудную жизнь ни разу не приходилось сталкиваться с необходимостью составлять подобные запросы.
  • ANB (04.05.09 09:57) [55]

    > каким образом смотрите план?

    F5 в девелопере


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

    Я сталкивался. Когда сталкивался - тогда и писал другим синтаксисом. Но это так редко бывает . . .
  • Кщд (04.05.09 10:17) [56]
    >Игорь Шевченко ©   (30.04.09 14:06) [54]
    >Вот что странно - за долгую и многотрудную жизнь ни разу не приходилось >сталкиваться с необходимостью составлять подобные запросы.
    очень редко, но случалось, поэтому сейчас, когда oracle залатал баги, связанные с join, пишу в join-синтаксисе
    собственно, против (+)-синтаксиса ничего против не имею
  • Кщд (04.05.09 10:18) [57]
    >ANB   (04.05.09 09:57) [55]
    >F5 в девелопере
    реальный план можно увидеть только в трейсе
    может случиться так, что Вы хинтами оптимизируете пустоту
  • ANB (04.05.09 15:15) [58]

    > реальный план можно увидеть только в трейсе
    > может случиться так, что Вы хинтами оптимизируете пустоту

    Ну ни разу еще не нарывался. Как задумано - так и работает.

    Если план по Ф5 показывает ерунду - запрос висит. Если показывает то, что надо - работает.

    Чисто теоретически, есно, возможны расхождения. Пока не нарывался.
    Иначе и смысла бы в он-лайн просмотре планов бы не было.
  • PEAKTOP © (04.05.09 16:57) [59]
    >sniknik ©   (24.04.09 11:08) [23]
    > не, конечно и там среди бухгалтеров попадаются отщепенцы,
    >  придумали такую вещь как шахматка... но и ее делают. чаще
    > всего "поворачивая"  полученный результат на клиенте, делая
    > из "высоты" "ширину". можно и на сервере, легко могу сделать
    > на access или mssql  но на FB боюсь их синтаксис не пройдет,
    >  даже не пытаться не стоит (а трудов чтобы разбираться задача
    > не стоит. глупая логика).


    Пытаться уже очень давно стоит.
    http://delphiplus.org/articles/ib/firebird-2-full-capability/1/index.html

    > ANB   (29.04.09 14:55) [48]
    > Если оптимизатор сразу дает примерно правильный план - я и не хинтую.


    В Firebird это может аукнуться. Например, генеришь IBExpert-ом  тестовых записей миллиона два-три, чтобы скучно ему не было. Выполняешь скрипт - вроде и план правильный подхватился. А потом на реальных данных "вес" индекса другой получается, т.к реальные данные далеко не равномерно распределенные случайные величины, как в генераторе IBExpert-a. И план твоего запроса (имеется в виду внутри ХП) после первого backup/restore "поедет" куда-то. Так что все-таки бывают случаи, когда планы иногда надо указывать явно. Лично у мну есть пример запроса с "дефолтным" планом, выполняющийся за 18 секунд, и "ручным", выполняющимся за миллисекунды.

    Зато при переходе от версии к версии (как это было при 1.5 -> 2.0) есть вероятность наступить на очень древние грабли с изменениями в оптимизаторе, когда твоя БД тупо не восстанавливается из бэкапа из-за кривых (по мнению новой версии) статически прописанных планов. И тогда начинается увлекательнейший квест с перелопачиванием штук 800-1000 хранимых процедур. Так что тут есть свои и плюсы и минусы.

    Есть еще третий, компромиссный вариант: хинты. Например, когда индексное поле попадает в условие WHERE, то к нему можно прибавлять 0, дабы отключить использование индекса. Такой изврат на данный момент времени дает похожий план запроса на разных версиях оптимизатора.
  • sniknik © (04.05.09 20:03) [60]
    > Пытаться уже очень давно стоит.
    > http://delphiplus.org/articles/ib/firebird-2-full-capability/1/index.html
    и где ты там увидел синтаксис access или mssql? или не понятен смысл сказанного?

    у mssql нет first, для access используется инструкция transform. для обоих, не обязательно (в одном случае даже нельзя подобную) делать процедуру, проще ограничится запросом. для access вложенные подзапросы группируются не так.

    а то, что в FB это как то возможно, так вроде ничего в моем высказывании этому не противоречит.
  • Кщд (05.05.09 07:11) [61]
    >ANB   (04.05.09 15:15) [58]
    >Чисто теоретически, есно, возможны расхождения. Пока не нарывался.
    в любой сколько-нибудь "тяжелой"(миллионники, запутанная логика в SQL) системе - это данность

    >Иначе и смысла бы в он-лайн просмотре планов бы не было.
    большого смысла и нет
    explain plan - это средство первой линии диагностики - поверхностной и приблизительной
  • Кщд (05.05.09 07:16) [62]
    >PEAKTOP ©   (04.05.09 16:57) [59]
    >В Firebird это может аукнуться. Например, генеришь IBExpert-ом  тестовых >записей миллиона два-три, чтобы скучно ему не было. Выполняешь скрипт - >вроде и план правильный подхватился. А потом на реальных данных "вес" >индекса другой получается, т.к реальные данные далеко не равномерно >распределенные случайные величины
    именно так
    это справедливо и для Oracle, и для MS SQL
    правильная структура данных, грамотное индексирование, сбор статистики - рецепт эффективной БД
    хинты уместны, как и говорил ANB, для разовых выборок, отчетов
    хинт в серверном коде - зло
  • Игорь Шевченко © (05.05.09 12:41) [63]

    > миллионники


    это что такое ?
  • Кщд (05.05.09 13:33) [64]
    >Игорь Шевченко ©   (05.05.09 12:41) [63]
    имел в виду таблицы с порядком записей 10^6 и выше
  • Игорь Шевченко © (05.05.09 13:50) [65]
    Кщд   (05.05.09 13:33) [64]

    Понятно. А вот такой вопрос - есть таблица, с порядком записей 10^8. Есть запрос к этой таблице и еще нескольким (у одной из нескольких порядок записей 10^6, у других несущественный (меньше 10^4))
    Оптимизатор определяет, что толстую таблицу он будет обрабатывать FULL SCAN, запрос выполняется порядка получаса. Создал я нужный индекс по толстой таблице (функция от одного поля и и еще набор полей), индекс стал использоваться, COST запроса сократился, IO сократились, запрос стал выполняться пару минут. Это при незагруженном сервере. А при загруженном сервере запрос выполняется полтора часа, то есть, в три раза медленней, чем при FULL SCAN толстой таблицы. Время выполнения запроса с FULL SCAN от загруженности сервера практически не зависит, полчаса, плюс-минус 5 минут.

    Oracle 10.2.0.3 под Linux, сервер достаточно толстый по памяти, процессору и проч. Статистика собирается регулярно, в том числе и системная.
    В сессии выставлены параметры:
    Optimizer_Index_Caching=90
    Optimizer_Index_Cost_Adj=40

    Вопрос в следующем: В какую строну рыть ? :)
  • ANB (05.05.09 14:05) [66]

    > В Firebird это может аукнуться. Например, генеришь IBExpert-
    > ом  тестовых записей миллиона два-три, чтобы скучно ему
    > не было. Выполняешь скрипт - вроде и план правильный подхватился.
    >  А потом на реальных данных "вес" индекса другой получается,
    >  т.к реальные данные далеко не равномерно распределенные
    > случайные величины, как в генераторе IBExpert-a. И план
    > твоего запроса (имеется в виду внутри ХП) после первого
    > backup/restore "поедет" куда-то. Так что все-таки бывают
    > случаи, когда планы иногда надо указывать явно. Лично у
    > мну есть пример запроса с "дефолтным" планом, выполняющийся
    > за 18 секунд, и "ручным", выполняющимся за миллисекунды.
    >

    1) Я план то смотрю на реальных данных. План, есно, может поехать в любой момент, но на то у нас и админы есть, чтобы возникшие тормоза выявлять и нам на правку отдавать. За год ни одного такого случая не было.
    2) У оракла - хинты - это комментарии, которые он волен игнорить.
  • ANB (05.05.09 14:10) [67]

    > в любой сколько-нибудь "тяжелой"(миллионники, запутанная
    > логика в SQL) системе - это данность

    Скорее всего ваши админы вообще мышей не ловят.
    У нас как раз запутанная логика в SQL, нету внешних ключей и все прочее, от чего нормальный архитектор БД пришел бы в ужас.
    Таблица с несколькими миллионами записей у нас считается маленькой.

    Однако, повторюсь, на наших базах ни разу не нарывался, что план на тесте по Ф5 не совпадает с планом на реалке по трэйсу.
  • ANB (05.05.09 14:30) [68]

    > хинт в серверном коде - зло

    Но неизбежное.
  • ANB (05.05.09 14:33) [69]

    > Вопрос в следующем: В какую строну рыть ? :)

    План покажи
  • Игорь Шевченко © (05.05.09 14:47) [70]

    > План покажи


    Смотри

    --------------------------------------------------------------------------------
    |Id  |Operation                       | Name           | Rows  | Bytes | Cost  |
    --------------------------------------------------------------------------------
    |  0 |SELECT STATEMENT                |                |  1940 |   251K| 30528 |
    |  1 | HASH JOIN                      |                |  1940 |   251K| 30528 |
    |  2 |  TABLE ACCESS FULL             |SMALLT1         |     9 |   117 |     2 |
    |  3 |  NESTED LOOPS ANTI             |                |  2511 |   294K| 30525 |
    |  4 |   HASH JOIN                    |                |  2582 |   252K| 30524 |
    |  5 |    NESTED LOOPS                |                |  2582 |   226K| 30519 |
    |  6 |     HASH JOIN                  |                | 17517 |   821K| 23499 |
    |  7 |      INDEX FULL SCAN           |IX_SMA_T2       |    80 |  2080 |     2 |
    |  8 |      TABLE ACCESS FULL         | BIG_T3         |    50M|  1069M| 22488 |
    |  9 |     TABLE ACCESS BY INDEX ROWID| MED_T4         |     1 |    42 |     1 |
    | 10 |      INDEX UNIQUE SCAN         | PK_MED_T4      |     1 |       |     1 |
    | 11 |    TABLE ACCESS FULL           | SMA_T5         | 13014 |   127K|     5 |
    | 12 |   INDEX UNIQUE SCAN            | IX_MED_T6      |   655 | 13100 |     1 |
    --------------------------------------------------------------------------------

  • Кщд (05.05.09 14:51) [71]
    >Игорь Шевченко ©   (05.05.09 13:50) [65]
    >COST запроса сократился, IO сократились, запрос стал выполняться пару >минут. Это при незагруженном сервере. А при загруженном сервере >запрос выполняется полтора часа, то есть, в три раза медленней
    если навскидку, то я бы посмотрел, чего ждет сессия(v$session_wait), в которой работает данный запрос, при выполнении на продуктивном сервере
    затем - смотрел бы на план из трейса

    кстати, ф-ция в function based index - deterministic?

    PS и, конечно, патчился бы до 10.2.0.4
    понимаю-понимаю, что патчить продуктив не всегда можно)
  • Кщд (05.05.09 14:54) [72]
    >Игорь Шевченко ©   (05.05.09 14:47) [70]
    навскидочку, если 6-ой hash join заменить на nested loops?
  • Игорь Шевченко © (05.05.09 15:10) [73]

    > кстати, ф-ция в function based index - deterministic?


    Явно задана в при создании индекса

    CREATE INDEX ix_ ON bigtable
    (field2, (CASE WHEN TRANSLATE(TRIM(field1),'x01234567890', 'x') IS NULL
                        THEN TO_NUMBER(field1)
                         ELSE 999999
               END),field3)



    Кщд   (05.05.09 14:54) [72]

    > навскидочку, если 6-ой hash join заменить на nested loops?


    Это план без индекса


    > если навскидку, то я бы посмотрел, чего ждет сессия(v$session_wait),
    >  в которой работает данный запрос


    db_file_sequential_read она ждет


    > затем - смотрел бы на план из трейса


    а это исключено политикой безопасности

    план смотрелся из SQL*Plus с включенной опцией autotrace

    собственно план с индексом:

    -------------------------------------------------------------------------------
    | Id  | Operation                        | Name       | Rows  | Bytes | Cost  |
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                 |            |  1940 |   251K|  7384 |
    |   1 |  HASH JOIN                       |            |  1940 |   251K|  7384 |
    |   2 |   TABLE ACCESS FULL              | SMALLT1    |     9 |   117 |     2 |
    |   3 |   NESTED LOOPS ANTI              |            |  2511 |   294K|  7381 |
    |   4 |    HASH JOIN                     |            |  2582 |   252K|  7380 |
    |   5 |     NESTED LOOPS                 |            |  2582 |   226K|  7375 |
    |   6 |      NESTED LOOPS                |            | 17517 |   821K|   355 |
    |   7 |       INDEX FULL SCAN            | IX_SMA_T2  |    80 |  2080 |     2 |
    |   8 |       TABLE ACCESS BY INDEX ROWID| BIG_T3     |   219 |  4818 |     4 |
    |   9 |        INDEX RANGE SCAN          | IX_        |    15 |       |     1 |
    |  10 |      TABLE ACCESS BY INDEX ROWID | MED_T4     |     1 |    42 |     1 |
    |  11 |       INDEX UNIQUE SCAN          | PK_MED_T4  |     1 |       |     1 |
    |  12 |     TABLE ACCESS FULL            | SMA_T5     | 13014 |   127K|     5 |
    |  13 |    INDEX UNIQUE SCAN             | IX_MED_T6  |   655 | 13100 |     1 |
    -------------------------------------------------------------------------------



    Из которого видно, что 6-ой HAS JOIN заменился на NESTED LOOPS
  • ANB (05.05.09 15:43) [74]
    |   8 |       TABLE ACCESS BY INDEX ROWID| BIG_T3     |   219 |  4818 |     4 |
    |   9 |        INDEX RANGE SCAN          | IX_        |    15 |       |     1 |

    Сколько всего записей в BIG_T3 и сколько примерно из них попадает в запрос ?

    Сколько записей в таблице индекса IX_SMA_T2 и сколько из них попадает в запрос при первичном отборе ?

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

    После он потерялся.
  • Игорь Шевченко © (05.05.09 16:17) [75]
    ANB   (05.05.09 15:43) [74]


    > Сколько всего записей в BIG_T3 и сколько примерно из них
    > попадает в запрос ?


    всего десятки миллионов, попадают десятки тысяч


    > Сколько записей в таблице индекса IX_SMA_T2 и сколько из
    > них попадает в запрос при первичном отборе ?


    Сколько-то тысяч, сколько-то сотен попадает.


    > Хотя даже навскидку - выкини нафик индекс


    Какой именно ?


    > С нагрузкой сервера твои тормоза никак не связаны - скорее
    > всего после создания индекса, он и таблица закэшировались
    > в память, что дало временный эффект ускорения.
    >
    > После он потерялся.


    То есть, через неделю после создания, работы на сервер, в выходные на пустом сервере он все еще оставался в кэше ?

    Любопытная жизнь у индексов.
  • Anatoly Podgoretsky © (05.05.09 17:03) [76]
    Может у тебя 2 террабайта памяти...
  • Игорь Шевченко © (05.05.09 17:06) [77]
    Anatoly Podgoretsky ©   (05.05.09 17:03) [76]

    Тогда бы не наблюдалось явления, описанного в [65], из двух Тб оно бы преспокойно быстренько выбиралось в течение недели, а не только по выходным. На выходные память не наращивают, это точно.
  • Игорь Шевченко © (05.05.09 17:35) [78]
    Кщд   (05.05.09 14:51) [71]

    Кстати, обманул насчет версии Oracle

    SQL> select banner from v$version;

    BANNER
    ----------------------------------------------------------------
    Oracle Database 10g Release 10.2.0.4.0 - 64bit Production
    PL/SQL Release 10.2.0.4.0 - Production
    CORE    10.2.0.4.0      Production
    TNS for Linux: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
  • Кщд (06.05.09 07:56) [79]
    >Игорь Шевченко ©   (05.05.09 17:35) [78]
    покажите, пожалуйста, сам запрос
  • Кщд (06.05.09 07:59) [80]
    >ANB   (05.05.09 14:10) [67]
    >Скорее всего ваши админы вообще мышей не ловят.
    никакой dba не в силах изменить простую аксиому: данные explain plan и данные трейса - это вовсе не одно и то же)
  • Игорь Шевченко © (06.05.09 11:16) [81]
    Кщд   (06.05.09 07:56) [79]


    > покажите, пожалуйста, сам запрос


    INSERT INTO tempt (f1,f2,f3,f4,f5)
    SELECT t4.f1,t4.f2,'FOO' t3,
          CASE WHEN t4.aa = 'BAR' THEN 'BAR'
               WHEN t4.aa = 'BAZ' THEN 'FOO'
          END f4, t4.f5
     FROM med_t4 t4, sma_t5 t5,smallt1 t1,bigtable big_t3,
          sma_t2 t2
    WHERE t4.aa IN ('BAR','BAZ')
      AND big_t3.f1 = t4.f1
      AND t4.bb BETWEEN :ParamS AND :ParamE
      AND t4.cc = t5.cc
      AND TRIM(t5.dd) = t1.dd
      AND t1.ee = :Param
      AND big_t3.zz = t2.field2
      AND CASE
            WHEN TRANSLATE(TRIM(big_t3.field2),'x01234567890', 'x') IS NULL
              THEN TO_NUMBER(big_t3.field2)
              ELSE 999999
          END = t2.yy
      AND big_t3.field3 BETWEEN t2.s AND t2.e
      AND t2.xx = :Param1
      AND NOT EXISTS (
         SELECT NULL FROM med_t6
            WHERE aaa = :param2 AND bbb = t4.f1
      )

  • Кщд (06.05.09 12:32) [82]
    >Игорь Шевченко ©   (06.05.09 11:16) [81]
    результаты тайминга  на сервере без нагрузки были приведены для insert или - всё же - для select?
    есть стойкое подозрение, что на продуктиве реальный план другой
    снять план из трейса категорически невозможно?
  • Игорь Шевченко © (06.05.09 12:59) [83]
    Кщд   (06.05.09 12:32) [82]


    > результаты тайминга  на сервере без нагрузки были приведены
    > для insert или - всё же - для select?


    Для insert, разумеется.


    > снять план из трейса категорически невозможно?


    Да, невозможно. План для SELECT с использованием AUTOTRACE снимался с выдачей данных, при этом время выполнения одного SELECT примерно соответствовало времени выполнения INSERT. Я к тому, что основная доля времени падает на SELECT
  • Кщд (06.05.09 13:12) [84]
    >Игорь Шевченко ©   (06.05.09 12:59) [83]
    в порядке эксперимента предложил бы
    1. убрать оставшийся hash join (индекс на sma_t5(cc))
    2. использовать --+ append

    если это выполнить возможно, то, пожалуйста, выложите планы и тайминги, но именно для insert

    PS
    как известно, были баги, связанные с тем, что в отлаженных select'ах при использовании в insert into select from "разлетались" планы
  • Игорь Шевченко © (06.05.09 13:38) [85]
    Кщд   (06.05.09 13:12) [84]


    > 2. использовать --+ append


    то, куда insert-ится - это global temporary table, смысла в append как-то не вижу.


    > 1. убрать оставшийся hash join (индекс на sma_t5(cc))


    Таблица sma_t5 мала - десятки тысяч записей.


    > PS
    > как известно, были баги, связанные с тем, что в отлаженных
    > select'ах при использовании в insert into select from "разлетались"
    > планы


    Дело в том, что как я писал:

    "План для SELECT с использованием AUTOTRACE снимался с выдачей данных, при этом время выполнения одного SELECT примерно соответствовало времени выполнения INSERT. Я к тому, что основная доля времени падает на SELECT"

    так что я бы не очень принимал во внимание "были баги при insert ... select"

    и INSERT и SELECT ждут dbfile sequential read и dbfile scattered read.

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

    Я даже не могу к себе данные перетащить и потрассировать запросы - у меня XE, а данных всяко больше 4-х Гб
  • Кщд (06.05.09 14:02) [86]
    >Игорь Шевченко ©   (06.05.09 13:38) [85]

    то, куда insert-ится - это global temporary table, смысла в append как-то не вижу.

    согласен


    Таблица sma_t5 мала - десятки тысяч записей.

    тем не менее, хотелось бы увидеть максимально оттюненный SQL и уже потом, разбираться с "тормозами"


    так что я бы не очень принимал во внимание "были баги при insert ... select"

    как понимаете, время не аргумент
    если план для insert показывает то же, что план select, то (при отсутствии возможности снять настоящий план из трейса) предложение снимается


    и INSERT и SELECT ждут dbfile sequential read и dbfile scattered read.

    т.е., другими словами, это индексные чтения и FTS, поэтому и хотел бы свести всё к индексным


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

    это я понял)
    таблицы и индексы проанализированы?
    есть подозрение(судя по кардинальности из плана), что нет
    возможность собрать статистику по ним имеется?
  • Игорь Шевченко © (06.05.09 14:33) [87]
    Кщд   (06.05.09 14:02) [86]

    Из поста [65] "Статистика собирается регулярно, в том числе и системная." :)


    > тем не менее, хотелось бы увидеть максимально оттюненный
    > SQL и уже потом, разбираться с "тормозами"


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

    Тут еще момент - сейчас индекс отключен, а развлекаться с ним я могу, когда сервер не занят, то есть, в очередные выходные.
  • Кщд (06.05.09 14:50) [88]
    >Игорь Шевченко ©   (06.05.09 14:33) [87]

    Из поста [65] "Статистика собирается регулярно, в том числе и системная." :)

    прошу прощения, взгляд "замылился")


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

    возможно, под нагрузкой собранная статистика становится недостоверной(в течение дня интенсивные insert/update/delete) и индекс слетает
    в общем, всё это без трейса, увы, гадание на кофейной гуще...
    ну, разве что посмотреть, на каком именно индексе висят ожидания sequential read
    и попробовать увеличить buffer cache

    как вариант выявления "отказа" индекса, явно хинтами стабилизировать план до того, который указывали, и проверить на скорость выполнения
  • Игорь Шевченко © (06.05.09 16:48) [89]
    Кщд   (06.05.09 14:50) [88]

    собрали трассировку с криками е.т.м :)

    Получили странное из статистики:

    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute      4      7.19     433.51      96337     323853         61         292
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        5      7.20     433.51      96337     323853         61         292



     Event waited on                             Times   Max. Wait  Total Waited
     ----------------------------------------   Waited  ----------  ------------
     db file sequential read                     96245        0.24        428.98
     db file scattered read                         11        0.00          0.03
     SQL*Net message to client                       4        0.00          0.00
     SQL*Net message from client                     4       51.29         51.32



    и

    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1     43.92    2150.75     567201    2856992       5844        4017
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2     43.92    2150.75     567201    2856992       5844        4017



     Event waited on                             Times   Max. Wait  Total Waited
     ----------------------------------------   Waited  ----------  ------------
     db file sequential read                    567130        0.26       2124.65
     latch: object queue header operation            2        0.00          0.00
     db file scattered read                          9        0.00          0.03
     SQL*Net message to client                       1        0.00          0.00
     SQL*Net message from client                     1        0.00          0.00



    Сильно не понравилось близость цифр elapsed на Execute и db file sequential read в ожиданиях.

    Будем думать.
  • Игорь Шевченко © (06.05.09 16:49) [90]
    План кстати не изменился
  • ANB (07.05.09 17:04) [91]
    Странноватая ситуация. Обычно индекс_ранг_скан слабо зависит от нагрузки.
    Я мог предположить, что завис шел при очистке целевой таблицы транкейтом (была у нас такая грабля), но тут явно другое.

    Скорее всего надо внимательно посмотреть на табличное пространство, в которое посажен новый функциональный индекс. Если тормоза начинаются только при нагрузке, то вероятно захлебывание диска при чтении. Можно попробовать перасадить индекс в другое табличное пространство для эксперимента.
  • Игорь Шевченко © (07.05.09 17:19) [92]

    > Странноватая ситуация


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

    В больших таблицах первого варианта по ~30 и ~50 миллионов, в больших таблицах второго варианта ~50 и ~150 миллионов, второй вариант выполняется быстрее и статистика ожиданий у него более похожа на правду.

    Я просто к чему - дело не в запросе. С запросами я бороться более или менее умею. Мне интересно, в чем может причина.


    > Скорее всего надо внимательно посмотреть на табличное пространство,
    >  в которое посажен новый функциональный индекс


    При внимательном анализе как плана, так и статистики ожиданий выяснилось, что больше всего ожиданий по времени не на этом (функциональном) индексе, а на другом.

    Все индексы в одном tablespace
  • ANB (08.05.09 16:07) [93]

    > При внимательном анализе как плана, так и статистики ожиданий
    > выяснилось, что больше всего ожиданий по времени не на этом
    > (функциональном) индексе, а на другом.

    Сколько всего строк в таблице с этим индексом и сколько из них отбирается ?

    Хотя если без нагрузки работает быстро . . .

    Табличное пространство дефрагментрировать не пробовали ?
  • Игорь Шевченко © (08.05.09 20:45) [94]
    ANB   (08.05.09 16:07) [93]

    Ты как тот раввин - "а жаль, еще столько идей было".


    > Табличное пространство дефрагментрировать не пробовали ?


    Пробовали, не помогло. На праздниках попробую ANALYZE INDEX VALIDATE STRUCTURE по индексам (их немного) таблиц проблемного запроса.
  • ANB (13.05.09 14:09) [95]

    > Ты как тот раввин - "а жаль, еще столько идей было".

    Угу. Оптимизация толстых запросов - это почти всегда пляски с бубном. :)

    На 2 запроса разбить не пробовал ? У нас частенько разбиение толстого запроса по нескольким таблицам на несколько отдельных инсертов (перекладкой) с селектом в связке по двум таблицам дает ускорение на порядок а то и на 2. И проблемный кусок быстрее выявляется.
  • Игорь Шевченко © (13.05.09 14:36) [96]

    > У нас частенько разбиение толстого запроса по нескольким
    > таблицам на несколько отдельных инсертов (перекладкой) с
    > селектом в связке по двум таблицам дает ускорение на порядок
    > а то и на 2.


    Это как ?
  • ANB (13.05.09 16:15) [97]
    insert into T_Rpt
    select
     *
    from
     T1
    ,T2
    ,T4
    ,T5
    ,T6
    where
     условия

    заменяем на несколько инсертов типа

    insert into T_Rpt_1
    select
     *
    from
     T1
    ,T2
    where
     условия

    insert into T_Rpt_2
    select
     *
    from
     T_Rpt_1
    ,T4
    where
     условия

    и. т. Есно с набором полей вместо *

    В каждой порции подбираем оптимальный план, (хэш джойн или нестед лупс), при надобности - распараллеливаем.

    Ресурсов, правда, жрет такой метод до хрена. Зато работает в приемлемые сроки. И отлаживать проще.
  • Игорь Шевченко © (13.05.09 17:21) [98]
    ANB   (13.05.09 16:15) [97]

    Такой путь неприемлем
  • Кщд (14.05.09 07:21) [99]
    >Игорь Шевченко ©   (06.05.09 16:48) [89]
    разберетесь, выложите, пожалуйста, здесь результат?

    >ANB   (13.05.09 14:09) [95]
    >Угу. Оптимизация толстых запросов - это почти всегда пляски с бубном. :)
    оптимизатор - это набор правил, статистики и багов
    бубна требуют лишь баги для разработки workaround
    да и то - проблема с последними - зачастую - решается прочтением соответствующей ноты с metalink
    поэтому всякое упоминание о "колдунстве" со стороны разработчиков БД лично я воспринимаю, как попытку набить себе цену
    уж извините)
  • Игорь Шевченко © (14.05.09 11:18) [100]
    Кщд   (14.05.09 07:21) [99]

    > разберетесь, выложите, пожалуйста, здесь результат?


    Постараюсь, только неизвестно, сколько времени займет этот процесс - он в фоновом режиме
  • имя (19.08.09 14:22) [101]
    Удалено модератором
  • имя (19.08.09 14:22) [102]
    Удалено модератором
 
Конференция "Базы" » Как составить запрос к базе [D7, FB 2]
Есть новые Нет новых   [134473   +32][b:0.001][p:0.009]