/* create two sets of tables which are identical except one set does not have foriegn keys defined. This file can be used to evaluate if the foreign keys improve query performance (are they used as indexes?) */ use ReportBuilderTraining --- --- cleanup from last run --- -- need to delete this first because of the foreign keys if object_id('evc.ReportCategory') is not null drop table evc.ReportCategory if object_id('evc.Report') is not null drop table evc.Report if object_id('evc.Category') is not null drop table evc.Category go -- need to delete this first because of the foreign keys if object_id('evc.Report2Category2') is not null drop table evc.Report2Category2 if object_id('evc.Report2') is not null drop table evc.Report2 if object_id('evc.Category2') is not null drop table evc.Category2 go --- --- Create tables --- create table evc.Report ( ReportID int not null ,Name varchar(50) null ,constraint evc_Report_PK primary key clustered (ReportID) ) create table evc.Category ( CategoryID int not null ,Name varchar(50) null ,constraint evc_Category_PK primary key clustered (CategoryID) ) create table evc.ReportCategory ( ReportId int not null ,CategoryId int not null ,constraint evc_ReportCategory_PK primary key clustered (ReportId, CategoryId) ) go --- --- Create tables --- create table evc.Report2 ( ReportID int not null ,Name varchar(50) null ,constraint evc_Report2_PK primary key clustered (ReportID) ) create table evc.Category2 ( CategoryID int not null ,Name varchar(50) null ,constraint evc_Category2_PK primary key clustered (CategoryID) ) create table evc.Report2Category2 ( ReportId int not null ,CategoryId int not null ,constraint evc_ReportCategory2_PK primary key clustered (ReportId, CategoryId) ) go --- --- Add foreign keys (only on the first set of tables) --- alter table evc.ReportCategory add foreign key (ReportID) references evc.Report(ReportId) on delete cascade on update cascade alter table evc.ReportCategory add foreign key (CategoryID) references evc.Category(CategoryID) on delete cascade on update cascade go --- --- Create data --- insert into evc.Report (ReportId, Name) values (1, 'Enrollment Counts of Diverse Students') insert into evc.Report (ReportId, Name) values (2, 'Graduation Counts of Diverse Student') insert into evc.Report (ReportId, Name) values (3, 'Enrollment Treds') insert into evc.Report (ReportId, Name) values (4, 'Graduation Trends') insert into evc.Category (CategoryId, Name) values (1, 'Enrolled Students') ,(2, 'Graduates') ,(3, 'Students At Risk') go select * from evc.Report select * from evc.Category insert into evc.ReportCategory (ReportId, CategoryId) values (1, 1) ,(1, 3) ,(2, 2) ,(2, 3) ,(3, 1) ,(4, 2) go --- --- Create data --- insert into evc.Report2 (ReportId, Name) values (1, 'Enrollment Counts of Diverse Students') insert into evc.Report2 (ReportId, Name) values (2, 'Graduation Counts of Diverse Student') insert into evc.Report2 (ReportId, Name) values (3, 'Enrollment Treds') insert into evc.Report2 (ReportId, Name) values (4, 'Graduation Trends') insert into evc.Category2 (CategoryId, Name) values (1, 'Enrolled Students') ,(2, 'Graduates') ,(3, 'Students At Risk') go select * from evc.Report2 select * from evc.Category2 insert into evc.Report2Category2 (ReportId, CategoryId) values (1, 1) ,(1, 3) ,(2, 2) ,(2, 3) ,(3, 1) ,(4, 2) go --- --- join the two different sets of tables and see if performance if different. --- select c.Name Category, r.Name Report from evc.Category c join evc.ReportCategory rc on c.CategoryID=rc.CategoryId join evc.Report r on rc.ReportId=r.ReportID order by 1, 2 select c.Name Category, r.Name Report from evc.Category2 c join evc.Report2Category2 rc on c.CategoryID=rc.CategoryId join evc.Report2 r on rc.ReportId=r.ReportID order by 1, 2 --- --- what if I only need results from one table? --- --- see http://www.scarydba.com/2010/11/22/do-foreign-key-constraints-help-performance/ --- and http://www.scarydba.com/2015/09/09/yes-foreign-keys-help-performance/ --- select r.Name Report from evc.Category c join evc.ReportCategory rc on c.CategoryID=rc.CategoryId join evc.Report r on rc.ReportId=r.ReportID --where c.CategoryId = 1 order by 1 select r.Name Report from evc.Category2 c join evc.Report2Category2 rc on c.CategoryID=rc.CategoryId join evc.Report2 r on rc.ReportId=r.ReportID --where c.CategoryId = 1 order by 1