Subject | Re: [firebird-support] Re: Query VERY slow |
---|---|
Author | Arno Brinkman |
Post date | 2004-03-09T00:37:56Z |
Hi,
<...>
PEDIDOVENDAID,
<...>
) AS
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);
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.
example.
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
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
should be different or the same by coincedence?
Is there any reference between NFI.NotaFiscalID and PV.PedidoVendaID?
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 :
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)))
Regards,
Arno Brinkman
ABVisie
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Firebird open source database (based on IB-OE) with many SQL-99 features :
http://www.firebirdsql.org
http://www.firebirdsql.info
http://www.fingerbird.de/
http://www.comunidade-firebird.org/
Support list for Interbase and Firebird users :
firebird-support@yahoogroups.com
Nederlandse firebird nieuwsgroep :
news://80.126.130.81
> >...snip...this
> >I can't say (without more information :-) what MSSQL did different on
> >query compared to FB, but i guess this :Suggestions, ideas are always welcome.
> >
> >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.... :)
> If I have a view with an outer join that is used across my application,optimizer
> sometimes the left join is ok, sometimes the where clause is just on the
> fields of the "right table" on a left join. I will ask you if the
> can analize this and turn this query in a join instead of left join.CREATE VIEW VNOTAFISCALITEM (
>
> See an example:
<...>
PEDIDOVENDAID,
<...>
) AS
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);
> This view join the invoice table (NotaFiscal) with the Sales Order Table"from
> (PedidoVenda), I could have Invoices without Sales Order, so I need a left
> join.
>
> Sometimes I use it with the following SQL (to show all Invoice Items
> related to some Sales Order):
>
> Select * from vNotaFiscalItem where PedidoVendaID = 9000
>
> this automatically could be identified by the optimizer to change the
> clause" to: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)
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.
> I done some tests and the change from an outer join to a join make theYes, the JOIN order can change and every table could use a index in this
> query MUCH FASTER !!! in FB 1.5 i got the following plan and times:
example.
> I have did some observations that with FB 1.0 the query will run muchFROM
> 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:
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)),PVIjoins" :)
> 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
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 INDEXI don't understand what you propose in the above two queries. Both results
> (RDB$PRIMARY47)),PVI INDEX (RDB$PRIMARY65)),PV INDEX (RDB$PRIMARY63)),JOIN
> (NOA INDEX (RDB$PRIMARY43),ME INDEX (RDB$PRIMARY45)))
> Time: 0.001 sec
should be different or the same by coincedence?
Is there any reference between NFI.NotaFiscalID and PV.PedidoVendaID?
> This is the most common usage... So the speedy is ok in the most cases...pvi.PedidoVendaId)
>
> This is used too: (To filter on CustomerID (EmpresaID) field)
> 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 =
> joinme.MultiEmpresaID)
> NaturezaOperacao noa on (noa.NaturezaOperacaoID =
> nfi.NaturezaOperacaoID) join
> MultiEmpresa me on (nf.MultiEmpresaID =
> whereI wonder if this is the most efficient PLAN, but it depends on how big is 1
> 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
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 :
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)))
Regards,
Arno Brinkman
ABVisie
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Firebird open source database (based on IB-OE) with many SQL-99 features :
http://www.firebirdsql.org
http://www.firebirdsql.info
http://www.fingerbird.de/
http://www.comunidade-firebird.org/
Support list for Interbase and Firebird users :
firebird-support@yahoogroups.com
Nederlandse firebird nieuwsgroep :
news://80.126.130.81