[quoted text, click to view] On 14 Mar 2004 06:27:57 GMT, Anita wrote:
>My query is very bad and I must avoid using the
>query like it. Although it does not have a long
>executon plan path, but I still do not understand
>which parts of the query that cause it takes
>a very long time. Could you help me ?
I'm far from calling myself an expert on this kind of things, but in
this case I think I can take a shot.
First of all: the length of an execution plan is not related to the
duration of query execution. It's the contents. In general: table
scans and sorting on large tables are bad, index scans are good.
In practice, this is very complicated stuff. I hardly ever try to
understand the execution plan. If I have to write queries that are
both complicated and either time-critical or operating on lots of data
(or both!), I always try a few different approaches to the query to
see which yields the best results.
[quoted text, click to view] >-------My query #2---------
>SELECT * FROM Tbl
>WHERE 1 = ( select top 1 case when product = tbl.product
> and price = tbl.price and
> orderid = tbl.orderid then 1
> else 0 end
> from tbl t
> where product = tbl.product
> order by product,price,orderid )
The inner query references the outer query. This is called a
correlated subquery. With just the where-condition, I guess that SQL
Server's optimizer would have changed it into an equivalent simple
self-join of the table, but I'd guess that the order and (especially)
the case preclude such action.
As it is, SQL Server will have to travers the outer query row by row;
for each row, the inner query has to be resolved. I don't know if the
inner query will produce a small or large result set; that would
depend on the number iof distinct products in the table. But the case
demands some logic to be performed on each row and the order by calls
for a sort of all the rows in the inner query's result set. My guess
is that this sort is the true bottleneck.
You already wrote that your actual table is 1,000,000 rows. Let's
assume a total of 100 different products; for the average product, the
inner query would yield a result set of 10,000 rows. to be sorted. If
the query optimizer recognises that the inner query would be the same
for all "outer" rows relating to the same product, it might actually
decide to execute the inner query only once per product. That would
let you get away with "only" 10,000 sorts of 10,000 rows. But you
might just as well get a whole 1,000,000 sorts of 10,000 rows.
BTW, judging from the execution times you posted, I'd guess that you
have no index on product, price, orderid. If you want to surprise
yourself (and you are allowed to experiment on the system the table's
residing on), try adding a clustered index (non-unique, if there can
be multiple rows with the same product, price, orderid combination) on
the table and then re-executing your version of the query.
Best, Hugo
--