This is pseudo-code:
Select
count(score)
from
myTable
join
HisTable on myTAble.id = HisTable.id
where
name='aaa'
group by
id
having
count(score) > 3
order by
(someField)
My question is about index. Where should I put the non-clustered index and the clustered index?
By which priority? (the aggregate? The order? The where? The join fields?)
In SQL Server, there are several basic considerations:
the clustering key is vitally important, and it should be chosen with care – it should be narrow, unique, static and possibly ever-increasing (the NUSE principle) – see Kim Tripp’s Ever-increasing clustering key – the Clustered Index Debate……….again! blog post for more detailed information on why those characteristics are important).
So your clustering key should be narrow – 4-byte INT is ideal, it should be UNIQUE and static, and this is perfectly handled by some kind of an
ID– especially if it’s anINT IDENTITY. GUID is significantly worse, variable-width VARCHAR fields are absolutely out of the questionevery foreign key column in a child table referencing a parent table should be part of a nonclustered index. This significantly speeds up JOINs and other operations
any column used in a
WHEREorORDER BYclause also is a good index candidate.But mind you: indexing is an art and a balancing act. Each additional index adds more overhead – don’t overdo your indices! Less is often more. Try to
and then see if your app performs OK. If it does – fine, let it be. If not: try to isolate the offending queries, and try to tune those. Don’t over-do your indexing by tuning each individual query – an index that might benefit one query can severely impact another one. It’s a matter of finding the best set of indices for your entire application.
Read Kim Tripp’s blog posts – all if you have the time. She’s the Queen of Indexing and offers tons of very valuable insights into what to do (and what not to do).