September 19, 2007 at 3:23 pm
Please help me in giving the suggestions for tuning the below query. The execution time is 12 min.
Below is the record count of each table :
FTProductUsage
- 35737259
FTContractValue - 1980410
FTContractRole - 130644561
VDTJobStartDT - 5480
LKCostCenter - 243
select a14.JSD_Month_ID Month_ID,
max(a14.JSD_MonthYr_DS) MonthYr_DS,
a13.CostCenter costcenter_DS,
max(a15.CostCenterName) CostCenterName,
a15.RegionID RegionID,
max(a15.RegionName) RegionName,
a15.ChannelID ChannelID,
max(a15.ChannelName) ChannelName,
sum(a11.Quantity) WJXBFS1
from FTProductUsage a11
join FTContractValue a12
on (a11.Account_ID = a12.Account_ID and
a11.Contract_KY = a12.Contract_KY)
join FTContractRole a13
on (a12.Contract_ID = a13.Contract_ID)
join VDTJobStartDT a14
on (a11.JobStartDT_KY = a14.JobStartDT_KY)
join LKCostCenter a15
on (a13.CostCenter = a15.CostCenter)
where (a11.ProductCapability in ('JobListing')
and a11.UsedFlg in (1)
and a11.HybridJobFlg in (0)
and a14.JSD_Month_ID = 200708
and a13.YearMonth = 200708
and a13.RoleType in ('PRIMREP'))
group by a14.JSD_Month_ID,
a13.CostCenter,
a15.RegionID,
a15.ChannelID
September 19, 2007 at 3:31 pm
start by changing all those "in" for "="
You need to know if the indexes are being used ( can you post the query plan )
In addition you should also check for fragmentation levels and satitstics
Cheers
* Noel
September 19, 2007 at 4:48 pm
Noel's most certainly correct (he usually is).
Make sure you place indices on the columns that are being used to
a) Join the tables
b) Perform the grouping
Include in the indices the fields that you're returning. This will prevent "bookmark/row lookups".
Is this the query that's always executed, or do you have the in's there because this is dynamically generated and thus you could have several values in each IN clause?
Could you perhaps post
a) The table definitions
b) Describe in words what you're trying to achieve rather than just posting the SQL... There could be a better way of doing it.
September 20, 2007 at 11:39 pm
In addition, the index definitions would assist and, if possible, the xml query plan (link, not post, it will be huge)
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
October 4, 2007 at 3:33 am
Hi,
In a test environment, take the query in the query analyzer then run (Index Tuning Wizard), it will recommend you creating/droping indexes.
Ahmed
October 5, 2007 at 8:19 am
One of the most important things was not given: the distribution of the values in the various tables. That will help determine if/which indexing will help.
Also, the optimizer 'should' be converting those single INs to equals for you I would expect.
Best,
Kevin G. Boles
SQL Server Consultant
SQL MVP 2007-2012
TheSQLGuru on googles mail service
October 5, 2007 at 10:45 am
Hi TheSQLGuru,
It sure, you're rigth 🙂 after converting the Ins to equals, it will be recommend to use the index tuning wizard. After you can you the profiler, yo want to go deeply.
Ahmed
October 9, 2007 at 6:34 am
The use of IN is a red herring and in this case makes no difference to the query. The DTA may well help you but really you need to analyse the query plan, just pasting a query into the forum has no real use as your hardware platform may well be a significant factor. I'm not sure if there's a good book on this for sql 2005 but the sql 2000 performance tuning handbook has a very good section and would certainly be a good place to start.
read up on indexing in BOL or/and get some inside SQL server books.
[font="Comic Sans MS"]The GrumpyOldDBA[/font]
www.grumpyolddba.co.uk
http://sqlblogcasts.com/blogs/grumpyolddba/
October 9, 2007 at 8:28 am
To add to that... are there Primary Keys on these tables? Is there a clustered index? Are the tables in a constant state of flux do to inserts, updates, and deletes? What is the Fill Factor for the tables? And what kind of locking/blocking are you experiencing when you run the code? Are any of these "tables" really "views"?
--Jeff Moden
Change is inevitable... Change for the better is not.
October 9, 2007 at 3:51 pm
After almost a month I don't think this OP is coming back ... 🙂
* Noel
October 9, 2007 at 10:28 pm
Heh... Thanks, Noel... I keep forgetting to check the date on the original post...
Oh well... keeps my hand at typing and I have seen it where the OP actually does come back after a month... very rare, though.
--Jeff Moden
Change is inevitable... Change for the better is not.
October 11, 2007 at 3:50 am
Ian Yates (9/19/2007)
Make sure you place indices on the columns that are being used to
a) Join the tables
b) Perform the grouping
c) Are used in the where clause
In case of multiple fields in one table, make indexes on the combined fields and also in the order in which you call them from the SQL statement, i.e. if your where clause looks like 'WHERE tbl1.fld1 = 'A' AND tbl1.fld2 = 'B', make sure the index for tbl1 is on fld1 and fld2 in that order.
October 12, 2007 at 7:26 am
Just for the record... I stumbled across this post by accident and found everyone's suggestions very helpful for my own query tuning.
Someone mentioned grouping on indexed fields.
I knew you should always try to join on indexed fields, but I wasn't aware that grouping had an impact.
Could someone elaborate on that a bit?
EDIT:
I've also heard that if you create an index on (for example): OrderID, CustomerID (say in tblCustomerOrders) that if you query that table you need to make sure you call it in the same order as it is in the index. However, I've ALSO heard that doesn't matter as the query optimizer will sort it out. Is there any truth to that?
October 12, 2007 at 7:37 am
In my experience it has the most impact when the aggregated columns are also in the index.
Consider a simple table
CREATE TABLE Payments (
PaymentKey INT IDENTITY PRIMARY KEY,
CustomerID int,
InvoiceID int,
PaymentDate datetime,
Amount Numeric(17,5)
)
Assume that the clustered index (and hence the physical order of the rows) is on the identity column. Assume there are lots of rows.
Take the following query.
SELECT CustomerID, SUM(Amount) FROM Payments group by customerID
Without any additional indexes, SQL will execute that as either a hash aggregate or a sort. That is because the data is not ordered by the grouped column, and hence requires hashing or sorting before it can be grouped.
Now add an index on CustomerID, Amount and run the same query. Now, the aggregate can be satisfied just with the non clustred index and, more importantly, the data is in order of customerID, so just a stream aggregate is required and the data does not have to be resorted or run through a hashing algorithm.
Does that make sense?
I think I'll write up a blog entry on this over the weekend, complete with some working examples.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
October 12, 2007 at 7:46 am
Maxer (10/12/2007)
I've also heard that if you create an index on (for example): OrderID, CustomerID (say in tblCustomerOrders) that if you query that table you need to make sure you call it in the same order as it is in the index. However, I've ALSO heard that doesn't matter as the query optimizer will sort it out. Is there any truth to that?
The query optimiser can sort it out, providing they are equality queries.
An index on two columns OrderID, CustomerID is seekable for any of the following query forms.
OrderId = x
OrderID = x and CustomerID = y
OrderID = x and CustomerID != y
Order ID = x and CustomerID > y
CustomerID = y and OrderID = x
It is not seekable for the following (can you see why? Imagine a phone book as an index on surname, firstname to see reasons). These will probably require partial or complete index scans or may not be used at all.
CustomerID = y
OrderID !=x and customerID = y
OrderID > x and customerID = y
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
Viewing 15 posts - 1 through 15 (of 21 total)
You must be logged in to reply to this topic. Login to reply