Hi Shawn:

Just wanted to publicly thank you for the time you took to help me. I think 
that it is important that guys like yourself who take time out from your busy 
work be appreciated when their solution made a huge difference.

I was developing an ASP application along with Crystal reports for a customer 
which was reporting from million of rows of data and my original approach 
resulted in very poor performance .. reports being VERY sluggish (45 mins to 
run some). I followed your concept and the same report that took 45 mins to run 
took 40 seconds!!!!

Unfortunately I could not implement it using MySql because the current version 
of MySql ODBC (3.51) did not expose the stored procedures to CR and I could not 
find an OleDb provider that will work for MySql. However, I ended up using Sql 
Server but I followed you suggestion and gained tremendous performance 
improvements.

Keep up the good work.

Best regards
Imran

---------------------------------------- Solution 
-------------------------------

Let me see if I can translate what you want in a query into regular language. I 
think you would like to see, grouped by date, customer, and product, the total 
cost and total sales for each (date,customer,product) triple along with each 
product's description ,code, and the customer's number and name. All of that 
will be limited to activity on or before midnight of a certain date. 

If I rephrased that correctly, here is how I would build your query. Step 1 is 
to perform the (date,customer,product) summations. By minimizing the number of 
rows, columns, and/or tables we need to summarize against, we improve 
performance. So I do this part of the analysis before I join in the other 
tables. 

Note: Date, time, and datetime literals are represented by single-quoted 
strings. You do not need the DATE() function to create a date literal. 


CREATE TEMPORARY TABLE tmpTotals ( 
        key(CustNo) 
        , key(ProdNo) 
) 
SELECT PostingDate 
        , CustNo 
        , ProdNo 
        , sum(Cost) as costs 
        , sum(Sales) as sales 
FROM salesmaster 
WHERE PostingDate <= '2005-09-01 00:00:00' 
GROUP BY PostingDate, CustNo, ProdNo; 

Step 2: collect the rest of the information for the report. 
SELECT CustNo 
        , c.Name as custname 
        , ProdNo 
        , p.Name as prodname 
        , costs 
        , sales 
        , PostingDate 
FROM tmpTotals tt 
LEFT JOIN customerintermediate c 
        ON c.CustNo = tt.CustNo 
LEFT JOIN productintermediate p 
        ON p.ProdNo = tt.ProdNo 
ORDER BY ... your choice... ; 

Step 3: The database is not your momma. Always clean up after yourself. 

DROP TEMPORARY TABLE tmpTotals; 

And you are done! The only trick to doing a sequence of statements in a row 
(like this) is that they all have to go through the same connection. As long as 
you do not close and re-open the connection between statements, any temp tables 
or @-variables you create or define remain in existence for the life of the 
connection. Depending on your connection library, you might be able to execute 
all three statements from a single request. Most likely, you will need to send 
them in one-at-a-time. 

Does this help you to organize your thoughts? 

Shawn Green
Database Administrator
Unimin Corporation - Spruce Pine 

Reply via email to