Hi Benjamin,
Thanks for reading my message an taking some time to give some help/sugggestion..
First you are right that I should have written the query in a readable form..
You gave some comments:
> SELECT brand.brandname,
> SUM((productorders.quantity)*(productorders.price)) AS turnover
> FROM orders
> LEFT JOIN productorders ON productorders.orderid = orders.id
> LEFT JOIN perfect_articles ON productorders.ordernr = articles.ordernr
> LEFT JOIN products ON products.id = articles.id
> LEFT JOIN brand ON products.brand = brand.id
> WHERE productorders.date >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 30 DAY),
>'%Y-%m-%d')
> AND productorders.date <= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 0 DAY),
>'%Y-%m-%d')
> AND orders.status != 2
> GROUP BY brand.brandname
> ORDER BY turnover asc
>
> Some comments:
>
> - Where is the table "articles" coming from? Did you mean
> "perfect_articles"? If not, you have no restriction on this table.
Yes, sorry, missed that one.. All the tables I originally made the query for have the
prefix perfect_ in front..
(perfect_articles, perfect_brand, perfect_productsorders.. I removed this to the make
it shorter and not make the query
look more complicated than it is.. (To answer your question: I missed the one perfect_
you saw, this had to be removed....)
> - Where is the table "orders"? I assume you meant "productorders"?
No, I do a select .... from orders...
Further in the query productorders is linked to orders..
Productorders is also then linked to the database which contains all articles ->
articles is linked to the products and products
linked to brand...
(Eg: the example: Microsoft (brand) -> Operating systems (products) -> Windows 95
(articles)
The person orders a windows 95 package.. The subtotals, way of payment etc if stored
in orders and all the articles he has ordered
is stored in productorders..
The reason why I needed to link productorders to orders is to have the option of
ignoring all records in which the order.status =
2.. (This is an number which tells me
that the order has been cancelled)
(I hope you understand, this is very hard to explain I would be better of drawing a
small chart..)
> - Do you really need LEFT JOINs instead of normal JOINs? At least the
> effect of the LEFT JOIN with "productorders" is lost by using
> "orders.status != 2" in the WHERE clause
>
> - You know that LEFT JOINs are usually slower than normal joins and
> therefore should only be used when needed? (Additonally, the result
> will differ in many cases)
Sorry, tell me I am dumb... I think that I understand SQL a bit, but I am by no ways
an expert..
I do try to get my hands on books from which I can learn something, but joins and
indexes are still an area from which I can learn a
lot of stuff..
In the past I always used a 'where' clause when joining stuff (eg: select
apples.description, pears.description from apples, pears
where pears.id = apples.id order by apples.id etc etc
Then I got my hands on examples which used a left join examples.. I have never tried a
normal join (sigh..), but thinking of it,
what is the difference between an left join and a normal join..??
(I will look at the chapter join in the mysql manual just now, so if I ask something
dumb which is explained in the manual then skip
the answer..)
I use PHP to format my output, so maybe a left join has something to do with the order
the columns are displayed which is no use for
me..??
> It doesn't matter if you use a ON clause instead of a WHERE clause
> with normal JOINS. The type of the JOIN does matter! And you cannot
> write LEFT JOINs with the constraint in the WHERE clause.
I understand what you say, only the last sentance I think I should go read the manual
to understand it.. (you cannot write left
joins with the contraints?? in the where clause..)
I did an explain on the query like you suggested/asked: (Please bear in mind that you
should think the 'perfect_' and
perfect_customer_ away for the above example...
These command (explain select...) are new to mee, but it looks like some useful
information and that I can optimize a lot by adding
some extra indexes...????
Original Query:
SELECT perfect_brand.brandname,
Sum((perfect_customer_productorders.quantity)*(perfect_customer_productorders.price))
AS omzet
FROM perfect_customer_orders
LEFT JOIN perfect_customer_productorders on
perfect_customer_productorders.orderid = perfect_customer_orders.id
LEFT JOIN perfect_articles on perfect_customer_productorders.ordernr =
perfect_articles.ordernr
LEFT JOIN perfect_products on perfect_products.id = perfect_articles.id
LEFT JOIN perfect_brand on perfect_products.brand = perfect_brand.id
WHERE (perfect_customer_productorders.date >= DATE_FORMAT( DATE_SUB( NOW() , INTERVAL
30 DAY ) , '%Y-%m-%d' )
AND perfect_customer_productorders.date <= DATE_FORMAT( DATE_SUB( NOW() ,
INTERVAL 0 DAY ) , '%Y-%m-%d' )
AND perfect_customer_orders.status != 2)
GROUP BY perfect_brand.brandname
ORDER BY omzet asc
explain above query: (Hope my tabs to get some layout stays intact)
I added an small gif to help when the following fails..
table type possible_keys key
key_len ref
rows Extra
perfect_customer_orders ALL
2585 where used
perfect_customer_productorders ALL
4410 where used
perfect_articles eq_ref PRIMARY PRIMARY
50
perfect_customer_productorders.ordernr 1
perfect_products ALL PRIMARY
180
perfect_brand ALL PRIMARY,id
16
show index from perfect_customer_orders
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part
perfect_customer_orders 0 PRIMARY 1 id A 2585
perfect_customer_orders 1 id 1 id A
show index from perfect_customer_productorders
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part
perfect_customer_productorders 0 PRIMARY 1 id A 4410
perfect_customer_productorders 1 id 1 id A
show index from perfect_customer_productorders
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part
perfect_customer_productorders 0 PRIMARY 1 id A 4410
perfect_customer_productorders 1 id 1 id A
show index from perfect_articles
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part
perfect_articles 0 PRIMARY 1 ordernr A 314
perfect_articles 1 nr 1 nr A
show index from perfect_products
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part
perfect_products 0 PRIMARY 1 id A 180
show index from perfect_brand
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part
perfect_brand 0 PRIMARY 1 id A 16
I am also going to do some reading myself on the normal join, thanks for your info...
Bye Bye
David
----- Original Message -----
From: "Benjamin Pflugmann" <[EMAIL PROTECTED]>
To: "David Bouw" <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Friday, July 20, 2001 7:11 PM
Subject: Re: Left Join very sloooowwww..
> Hello.
>
> [...]
> > Here is the query
> >
>
> [query reformatted... btw, it would have been nice if you had done this at first]
> SELECT brand.brandname,
> SUM((productorders.quantity)*(productorders.price)) AS turnover
> FROM orders
> LEFT JOIN productorders ON productorders.orderid = orders.id
> LEFT JOIN perfect_articles ON productorders.ordernr = articles.ordernr
> LEFT JOIN products ON products.id = articles.id
> LEFT JOIN brand ON products.brand = brand.id
> WHERE productorders.date >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 30 DAY),
>'%Y-%m-%d')
> AND productorders.date <= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 0 DAY),
>'%Y-%m-%d')
> AND orders.status != 2
> GROUP BY brand.brandname
> ORDER BY turnover asc
>
> Some comments:
>
> - Where is the table "articles" coming from? Did you mean
> "perfect_articles"? If not, you have no restriction on this table.
>
> - Where is the table "orders"? I assume you meant "productorders"?
>
> - Do you really need LEFT JOINs instead of normal JOINs? At least the
> effect of the LEFT JOIN with "productorders" is lost by using
> "orders.status != 2" in the WHERE clause
>
> - You know that LEFT JOINs are usually slower than normal joins and
> therefore should only be used when needed? (Additonally, the result
> will differ in many cases)
>
> [...]
> > I need to do the above query about 4 times for different intervals and in this
>case it then takes about 15 minutes to
complete...
> > (Pentium III 800 machine with 128 MB)
> [...]
>
> We need to see the output of
>
> EXPLAIN SELECT ...
> SHOW INDEX FROM brand
> SHOW INDEX FROM productorders
> SHOW INDEX FROM perfect_articles
> SHOW INDEX FROM products
> SHOW INDEX FROM orders
>
> > It looks that as soon as if I start to link a table with more than
> > 1000 records the machine is having a hard time.. Is it better to use
> > a where clause to link the tables..??
>
> It doesn't matter if you use a ON clause instead of a WHERE clause
> with normal JOINS. The type of the JOIN does matter! And you cannot
> write LEFT JOINs with the constraint in the WHERE clause.
>
> Bye,
>
> Benjamin.
>
>
---------------------------------------------------------------------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)
To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php