NT> что касается явного join и вставки выборки из sp первой, то ИМХО парсеру это
NT> побоку, план остается тотже.

    при явном Join с первой Sp план НЕМНОГО другой, ну даже если
    одинаков - то это не означает что выборка будет происходить так же ...
    Это только означает что будут использовать те-же индексы и в том же
    порядке. НО у SP НЕТ индексов при select * from SP происходит
    ПОЛНОЕ чтение, грубо говоря Natural. Исходя из этого логично
    было-бы делать выборку из SP только 1 раз :)
    Особый выиграш будет если SP возвращает много меньше записей
    чем связанная таблица. А у тебя, с неявным join, получается почти
    декартово произведение таблиц - потому и медленнее т.к. для
    КАЖДОЙ записи из декартового произведения в случае
    select * from tbl1, tbl2, SP ...
    SP будет вызвана Count(Tbl1) * Count(tbl2) раз, а для
    select * from tbl1, tbl2
     where tbl1=tbl2
       and exists (select * from SP(tbl1)) ...
    SP будет вызвана меньшее число раз т.к. EXISTS вызывается ПОСЛЕ
    отработки доп. условий в WHERE т.е. над уже меньшим множеством
    нежели Count(Tbl1) * Count(tbl2)

NT> Так что на таком запросе exists (select from sp) получается быстрее минимум
NT> в три раза, вот меня и интересует почему?

    Я/ выше обьяснил, сделай пробу, убрав доп. условия и оставив
    только связки, например:
     
     select p.name,p.fullname,p.description,
               sum(di.qty),di.price_prov,di.price,di.discount,
               d.date_docum,d2.date_docum,f.name,g.name,f.code
        from products p, docum_items di, documents d, firms f,
             product_cards pc, docum_items di2, documents d2, groups g,
             (select id from recurs_groups(0)) rg
        where (p.id_product = di.id_product)
          and rg.id=p.id_group
          and (d.id_docum = di.id_docum)
          and (d.id_firm = f.id_firm)
          and (di.id_card = pc.id_card)
          and (pc.id_docitem = di2.id_docitem)
          and (di2.id_docum = d2.id_docum)
          and (p.id_group = g.id_group)    
        group by p.name,p.fullname,p.description, di.price_prov,di.price,
              di.discount,d.date_docum,d2.date_docum,f.name,g.name,f.code
    
    и

     select p.name,p.fullname,p.description,
               sum(di.qty),di.price_prov,di.price,di.discount,
               d.date_docum,d2.date_docum,f.name,g.name,f.code
        from products p, docum_items di, documents d, firms f,
             product_cards pc, docum_items di2, documents d2, groups g

        where (p.id_product = di.id_product)
          and exists (select id from recurs_groups(0) where id=p.id_group)
          and (d.id_docum = di.id_docum)
          and (d.id_firm = f.id_firm)
          and (di.id_card = pc.id_card)
          and (pc.id_docitem = di2.id_docitem)
          and (di2.id_docum = d2.id_docum)
          and (p.id_group = g.id_group)
        group by p.name,p.fullname,p.description, di.price_prov,di.price,
              di.discount,d.date_docum,d2.date_docum,f.name,g.name,f.code
    

    - я уверен что разница НАМНОГО уменьшится

NT> Да и привык я за много лет к такому способу написания запросов.

    Ну вот против этого нет аргументов кроме как:
    "привычки рано или поздно ПРИХОДИТСЯ менять ..." ;)

PS: Ещё раз рекомендую http://ibase.ru/devinfo/joins.htm,
    не поленись почитай ...
    
С уважением,
Константин Григорьевич.
===============


Ответить