Subject | Re: [firebird-support] Re: Query VERY slow |
---|---|
Author | Alexandre Benson Smith |
Post date | 2004-03-09T01:17:40Z |
At 01:37 09/03/2004 +0100, you wrote:
could be more time consuming to apply then make the queries smarter (i.e.
make the programmer smarter).... :)
Item) and NotaFiscalItem (Invoice Item) because one invoice can have items
from diferent sales order, I get the NotaFiscal (Invoice) joining
PedidoVendaItem to NotaFiscalItem and NotaFiscalItem to NotaFiscal or is
this case I got PedidoVenda (Sales Order) joining NotaFiscalItem (Invoice
Item) to PedidoVendaItem (Sales Order Item) and PedidoVendaItem to
PedidoVenda (Sales Order).
from
InvoiceItem II left join
SalesOrderItem SOI on (SOI.SalesOrderItemID = II.SalesOrderItemID) left
join
SalesOrder SO on (SO.SalesORderID = SOI.SalesOrderID) join
Invoice I on (I.InvoiceID = II.InvoiceID)
is the same as
from
InvoiceItem II join
Invoice I on (I.InvoiceID = II.InvoiceID) left join
SalesOrderItem SOI on (SOI.SalesOrderItemID = II.SalesOrderItemID) left
join
SalesOrder SO on (SO.SalesORderID = SOI.SalesOrderID)
The optimizer could understand this are equal queries ???
In the first I Filter on PedidoVendaID to show all Invoice Items from a
given Sales Order and on the second I filter on NotaFiscalID to show all
InvoiceItem from a given Invoice. I just give those examples to show that
if I filter on the tables on the left side the speedy is great...
you wish... I just don't put it because the message was big enough... :)
Index RDB$FOREIGN170 cannot be used in the specified plan
select
PV.PEdidoVendaID
from
NotaFiscalItem nfi join
NotaFiscal nf on (nf.NotaFiscalId = nfi.NotaFiscalId) join
NaturezaOperacao noa on (noa.NaturezaOperacaoID =
nfi.NaturezaOperacaoID) join
MultiEmpresa me on (nf.MultiEmpresaID =
me.MultiEmpresaID) left join
PedidoVendaItem pvi on (pvi.PedidoVendaItemId =
nfi.PedidoVendaItemId) left join
PedidoVenda pv on (pv.PedidoVendaId = pvi.PedidoVendaId)
where
NF.EmpresaID = 3000
PLAN JOIN (JOIN (JOIN (JOIN (NF INDEX (RDB$PRIMARY47), NFI INDEX
(RDB$FOREIGN170)),PVI
INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN (NOA INDEX
(RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
Index RDB$FOREIGN170 cannot be used in the specified plan
:(
So could not see if it's faster
I tried
select
*
from
NotaFiscalItem nfi join
NotaFiscal nf on (nf.NotaFiscalId = nfi.NotaFiscalId) join
NaturezaOperacao noa on (noa.NaturezaOperacaoID =
nfi.NaturezaOperacaoID) join
MultiEmpresa me on (nf.MultiEmpresaID =
me.MultiEmpresaID) left join
PedidoVendaItem pvi on (pvi.PedidoVendaItemId =
nfi.PedidoVendaItemId) left join
PedidoVenda pv on (pv.PedidoVendaId = pvi.PedidoVendaId)
where
NF.EmpresaID = 3000
the plan is:
PLAN JOIN (JOIN (JOIN (ME NATURAL,NF INDEX (RDB$FOREIGN158),NFI INDEX
(RDB$FOREIGN170),NOA INDEX (RDB$PRIMARY43)),PVI INDEX (RDB$PRIMARY65)),PV
INDEX (RDB$PRIMARY63))
Time 0.007 sec
because of left joins are in the end, plan is diferent and much more
faster... So I have to still put the left joins at the end in FB 1.5...
In fact I don't understand well plans... I think it is confuse to read a
plan.... When I need to optimize a query I run it on IBPlanAnalizer, I
understand better the plan looking at the generated plan tree...
Alexandre Benson Smith
Development
THOR Software e Comercial Ltda.
Santo Andre - Sao Paulo - Brazil
www.thorsoftware.com.br
----------
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.596 / Virus Database: 379 - Release Date: 26/02/2004
[Non-text portions of this message have been removed]
>Hi,Sometimes I just tend to over simplify the things... And my suggestions
>
> > >...snip...
> > >I can't say (without more information :-) what MSSQL did different on
>this
> > >query compared to FB, but i guess this :
> > >
> > >The MSSQL optimizer is clever enough to see that the LEFT JOIN has an
> > >condition in the where clause and turns it into a INNER JOIN. You can see
> > >this by looking at the Execution PLAN in the SQL Query Analyzer.
> >
> > Hi Arno,
> >
> > This is a thing that I wish to ask you, for a long time.... :)
>
>Suggestions, ideas are always welcome.
could be more time consuming to apply then make the queries smarter (i.e.
make the programmer smarter).... :)
>FROMOh yeah... In fact the relation are between PedidoVendaItem (Sales Order
> NotaFiscalItem nfi
> JOIN NotaFiscal nf ON (nf.NotaFiscalId = nfi.NotaFiscalId)
> JOIN NaturezaOperacao noa ON (noa.NaturezaOperacaoID =
>nfi.NaturezaOperacaoID)
> JOIN MultiEmpresa me ON (nf.MultiEmpresaID = me.MultiEmpresaID)
> JOIN PedidoVendaItem pvi ON (pvi.PedidoVendaItemId =
>nfi.PedidoVendaItemId)
> JOIN PedidoVenda pv ON (pv.PedidoVendaId = pvi.PedidoVendaId);
>
>Indeed not only the LEFT JOIN from "PedidoVenda" should be changed, but also
>the LEFT JOIN from "PedidoVendaItem". Because there's a equality in the ON
>conditions for the "PedidoVenda" JOIN this is possible.
Item) and NotaFiscalItem (Invoice Item) because one invoice can have items
from diferent sales order, I get the NotaFiscal (Invoice) joining
PedidoVendaItem to NotaFiscalItem and NotaFiscalItem to NotaFiscal or is
this case I got PedidoVenda (Sales Order) joining NotaFiscalItem (Invoice
Item) to PedidoVendaItem (Sales Order Item) and PedidoVendaItem to
PedidoVenda (Sales Order).
> > I done some tests and the change from an outer join to a join make theThe optimizer could know that
> > query MUCH FASTER !!! in FB 1.5 i got the following plan and times:
>
>Yes, the JOIN order can change and every table could use a index in this
>example.
>
from
InvoiceItem II left join
SalesOrderItem SOI on (SOI.SalesOrderItemID = II.SalesOrderItemID) left
join
SalesOrder SO on (SO.SalesORderID = SOI.SalesOrderID) join
Invoice I on (I.InvoiceID = II.InvoiceID)
is the same as
from
InvoiceItem II join
Invoice I on (I.InvoiceID = II.InvoiceID) left join
SalesOrderItem SOI on (SOI.SalesOrderItemID = II.SalesOrderItemID) left
join
SalesOrder SO on (SO.SalesORderID = SOI.SalesOrderID)
The optimizer could understand this are equal queries ???
> > I have did some observations that with FB 1.0 the query will run muchYou are correct, the results SHOULD be diferent... Those are just examples...
> > faster if you put the "left joins" after all "joins". In FB 1.5 I did some
> > tests and the both return the same execution plan. but when I was writing
> > this message I did another test... If I change the "from clause" to:
>
>FROM
> NotaFiscalItem nfi
> JOIN NotaFiscal nf ON (nf.NotaFiscalId = nfi.NotaFiscalId)
> LEFT JOIN PedidoVendaItem pvi ON (pvi.PedidoVendaItemId =
>nfi.PedidoVendaItemId)
> LEFT JOIN PedidoVenda pv ON (pv.PedidoVendaId = pvi.PedidoVendaId)
> JOIN NaturezaOperacao noa ON (noa.NaturezaOperacaoID =
>nfi.NaturezaOperacaoID)
> JOIN MultiEmpresa me ON (nf.MultiEmpresaID = me.MultiEmpresaID)
>WHERE
> PV.PedidoVendaID = 9000
>
> > PLAN JOIN (JOIN (JOIN (JOIN (NFI NATURAL,NF INDEX (RDB$PRIMARY47)),PVI
> > INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN (NOA INDEX
> > (RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
> > Time: 4.05 sec
>
>
> > When I filter on fileds of the tables on the "left side" of the "left
>joins" :)
>
>FROM
> NotaFiscalItem nfi
> JOIN NotaFiscal nf ON (nf.NotaFiscalId = nfi.NotaFiscalId)
> LEFT JOIN PedidoVendaItem pvi ON (pvi.PedidoVendaItemId =
>nfi.PedidoVendaItemId)
> LEFT JOIN PedidoVenda pv ON (pv.PedidoVendaId = pvi.PedidoVendaId)
> JOIN NaturezaOperacao noa ON (noa.NaturezaOperacaoID =
>nfi.NaturezaOperacaoID)
> JOIN MultiEmpresa me ON (nf.MultiEmpresaID = me.MultiEmpresaID)
>WHERE
> NFI.NotaFiscalID = 9000
>
> > PLAN JOIN (JOIN (JOIN (JOIN (NFI INDEX (RDB$FOREIGN170),NF INDEX
> > (RDB$PRIMARY47)),PVI INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN
> > (NOA INDEX (RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
> > Time: 0.001 sec
>
>I don't understand what you propose in the above two queries. Both results
>should be different or the same by coincedence?
>Is there any reference between NFI.NotaFiscalID and PV.PedidoVendaID?
>
In the first I Filter on PedidoVendaID to show all Invoice Items from a
given Sales Order and on the second I filter on NotaFiscalID to show all
InvoiceItem from a given Invoice. I just give those examples to show that
if I filter on the tables on the left side the speedy is great...
> > This is used too: (To filter on CustomerID (EmpresaID) field)I can give full metadata for the involved tables and indices statistcs if
> > from
> > NotaFiscalItem nfi join
> > NotaFiscal nf on (nf.NotaFiscalId = nfi.NotaFiscalId)
> > left join
> > PedidoVendaItem pvi on (pvi.PedidoVendaItemId =
> > nfi.PedidoVendaItemId) left join
> > PedidoVenda pv on (pv.PedidoVendaId =
>pvi.PedidoVendaId)
> > join
> > NaturezaOperacao noa on (noa.NaturezaOperacaoID =
> > nfi.NaturezaOperacaoID) join
> > MultiEmpresa me on (nf.MultiEmpresaID =
>me.MultiEmpresaID)
> > where
> > NF.EmpresaID = 3000
> >
> > PLAN JOIN (JOIN (JOIN (JOIN (NFI NATURAL,NF INDEX (RDB$PRIMARY47)),PVI
> > INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN (NOA INDEX
> > (RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
> > Time: 1.0623 sec
>
>I wonder if this is the most efficient PLAN, but it depends on how big is 1
>record for the NotaFiscalItem and for NotaFiscal. Assuming that there are
>many more NotaFiscalItem records than NotaFiscal (and looking back on your
>record-info i see it is ;-) then i expected NotaFiscal at the first place.
>In fact i expected this kind of PLAN :
you wish... I just don't put it because the message was big enough... :)
>PLAN JOIN (JOIN (JOIN (JOIN (NF INDEX (RDB$PRIMARY47), NFI INDEXI tried the suggested plan... but I got
>(RDB$FOREIGN170)),PVI
> INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN (NOA INDEX
> (RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
>
Index RDB$FOREIGN170 cannot be used in the specified plan
select
PV.PEdidoVendaID
from
NotaFiscalItem nfi join
NotaFiscal nf on (nf.NotaFiscalId = nfi.NotaFiscalId) join
NaturezaOperacao noa on (noa.NaturezaOperacaoID =
nfi.NaturezaOperacaoID) join
MultiEmpresa me on (nf.MultiEmpresaID =
me.MultiEmpresaID) left join
PedidoVendaItem pvi on (pvi.PedidoVendaItemId =
nfi.PedidoVendaItemId) left join
PedidoVenda pv on (pv.PedidoVendaId = pvi.PedidoVendaId)
where
NF.EmpresaID = 3000
PLAN JOIN (JOIN (JOIN (JOIN (NF INDEX (RDB$PRIMARY47), NFI INDEX
(RDB$FOREIGN170)),PVI
INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN (NOA INDEX
(RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
Index RDB$FOREIGN170 cannot be used in the specified plan
:(
So could not see if it's faster
I tried
select
*
from
NotaFiscalItem nfi join
NotaFiscal nf on (nf.NotaFiscalId = nfi.NotaFiscalId) join
NaturezaOperacao noa on (noa.NaturezaOperacaoID =
nfi.NaturezaOperacaoID) join
MultiEmpresa me on (nf.MultiEmpresaID =
me.MultiEmpresaID) left join
PedidoVendaItem pvi on (pvi.PedidoVendaItemId =
nfi.PedidoVendaItemId) left join
PedidoVenda pv on (pv.PedidoVendaId = pvi.PedidoVendaId)
where
NF.EmpresaID = 3000
the plan is:
PLAN JOIN (JOIN (JOIN (ME NATURAL,NF INDEX (RDB$FOREIGN158),NFI INDEX
(RDB$FOREIGN170),NOA INDEX (RDB$PRIMARY43)),PVI INDEX (RDB$PRIMARY65)),PV
INDEX (RDB$PRIMARY63))
Time 0.007 sec
because of left joins are in the end, plan is diferent and much more
faster... So I have to still put the left joins at the end in FB 1.5...
In fact I don't understand well plans... I think it is confuse to read a
plan.... When I need to optimize a query I run it on IBPlanAnalizer, I
understand better the plan looking at the generated plan tree...
>Regards,Thanks again for your time and help....
>Arno Brinkman
>ABVisie
Alexandre Benson Smith
Development
THOR Software e Comercial Ltda.
Santo Andre - Sao Paulo - Brazil
www.thorsoftware.com.br
----------
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.596 / Virus Database: 379 - Release Date: 26/02/2004
[Non-text portions of this message have been removed]