SQL Server 2012 Enterprise. I have two tables with a FK relationship. The referencing column in the child table is NOT NULL. The FK is trusted. I create a view that joins the two tables with an INNER JOIN on the foreign key column and no filter. When I SELECT COUNT(*) from the view, it returns the count of rows in the child table (as expected), but looking at actual execution plan, it reads the parent table to do so. I see no reason to read from the parent table. The trusted FK on a NOT NULL column in the child table means that for every row in the child table there HAS to be a corresponding row in the parent table, so reading the parent table should be unnecessary. If I change the view's join to an OUTER JOIN, the parent table is not read with a SELECT COUNT(*) from the view. Is this a shortcoming in the optimizer (not really a bug), or am I missing something? Here's an example:
USE tempdb;
GO
IF OBJECT_ID('dbo.vChild') IS NOT NULL DROP VIEW dbo.vChild;
IF OBJECT_ID('dbo.Child') IS NOT NULL DROP TABLE dbo.Child;
IF OBJECT_ID('dbo.Parent') IS NOT NULL DROP TABLE dbo.Parent;
CREATE TABLE dbo.Parent (PKey int NOT NULL PRIMARY KEY,
SomeCol varchar(10) NOT NULL);
GO
CREATE TABLE dbo.Child (PKey int NOT NULL,
SeqNum int NOT NULL,
CONSTRAINT ChildPK PRIMARY KEY (PKey, SeqNum));
ALTER TABLE dbo.Child WITH CHECK ADD CONSTRAINT FK_Parent_Child FOREIGN KEY(PKey)
REFERENCES dbo.Parent (PKey);
GO
select is_not_trusted, * from sys.foreign_keys
WHERE [name] = 'FK_Parent_Child';
GO
CREATE VIEW dbo.vChild AS
SELECT C.PKey, C.SeqNum, P.SomeCol
FROM dbo.Child AS C
JOIN dbo.Parent AS P
ON C.PKey = P.PKey
GO
SELECT COUNT(*) FROM dbo.vChild;
Thanks, Vern
Vern Rabe