views:

85

answers:

5

I have the following tables:

Financial:

  • PK_FinancialID
  • FK_SchoolID

School:

  • PK_SchoolID

Class:

  • PK_ClassID
  • FK_SchoolID
  • ClassName

Both Class and Financial have Foreign Key relationships to School. I want to make a query that would show all classes that are related to Financial rows that meet certain criteria.

Initially I think to construct the query as follows:

Select Class.ClassName
From Class
Join School on Class.FK_SchoolID = School.PK_SchoolID
Join Financial on Financial.FK_SchoolID = Schol.PK_SchoolID
Where Financial ... -- define criteria

However, since both Financial and Class are joined on the PK_SchoolID column, it should be possible to rewrite the query as follows (cutting out the School table and joining Class and Financial directly):

Select Class.ClassName
From Class
Join Financial on Financial.FK_SchoolID = Class.FK_SchoolID
Where Financial ... -- define criteria

Which approach is preferable from a sql perspective? Would including the School table make performance better because the actual PK record is referenced (and thus a Clustered Index can be referenced)? Or does that not really matter? Anything that I am missing?

Platform: Sql Server 2005. All tables have their PK and FK columns properly declared and defined.

A: 

I'd say you're fine to leave out the actual school table. Don't see anything wrong with that.

As far as performance goes: I'm not really sure, but I'd say it would be faster because you have one less table to join - but I'm not an expert in that area...

Franz
+2  A: 

Yes, the index most definitely affects the performance.

Just add an index for the FK_SchoolID in the Financial table so that there is an index that the query can use.

Note that adding another index gives a slight performance hit when you add or delete records in the table. This is often outweighed by the big performance gain you get when querying the table, but it's the reason why you should be somewhat restrictive with adding indexes and don't just add indexes to all fields.

Guffa
"The index most definitely affects performance" - so then I should join with Schools?"All tables have their PK and FK columns properly declared and defined" - so there is already an index for FK_SchoolID in the Financial table.
Yaakov Ellis
@Yaakov: You don't need to use the index in the Schools table if there is an index elsewhere that can be used. If you have added an index for FK_SchoolID already then the query will use it, but indexes are not added automatically for foreign keys, only for primary keys.
Guffa
+3  A: 

If you don't need School, don't join School. If you wan't this query to run fast, create index on FK_SchoolID of Financial table. It looks as if you have n-1-1 relation between Class-School-Financial, so you should even create unique index on Financial. You shouldn't (in most cases) add additional tables to make query faster, just optimize used.

EDIT

If you select only ClassName, maybe what you need is:

Select Class.ClassName
From Class
Where Exists 
    (select * from Financial 
    where (Financial.FK_SchoolID = Class.FK_SchoolID) and (...))

It may be faster than other solutions and more understandable.

LukLed
There is already an index on Financial.FK_SchoolID. I can't make it unique, as there can be many Financial rows for each school (just as there can be many classes for each school)
Yaakov Ellis
It is possible that you have one Class multiple in result set?
LukLed
Yeah - forgot to mention that their is column grouping involved. Didn't think it directly relevant to the issue.
Yaakov Ellis
Everything is important. Maybe you don't need joins, but WHERE EXISTS() and this may be faster and cleaner solution.
LukLed
+1  A: 

Try the following:

Select Class.ClassName
From Class
Inner Join Financial on Financial.FK_SchoolID = Class.FK_SchoolID
Where Financial....yourcriteria

No need to join school table.

Himadri
+1  A: 

Seems to me that both of your examples are wrong. The fact that a school is listed as financial and that the school offers classes, does not mean that a specific class is a financial class -- it can be an art class from an another course. Seems that this is a weakness of the whole model, nothing to do with your SQL technique -- or maybe I do not understand the underlying model and all special constraints you may have. However, here is an example of a similar model:

  • One school can offer many courses; a course can be offered by several schools.
  • Each school may have specific name and description for a "generic" course.
  • One certificate requires several courses; a course may be required by many certificates.

    alt text
Damir Sudarevic
Financial is not the type of class. It is a file containing budgetary information. Budget rows can be related to specific schools (there is a different ClassType table that defines the type of class).
Yaakov Ellis