肯定的@Jonathan提供的答案将提高性能,如果'城市'列有单独NonClustered指数。如果不是这两个执行计划都会导致SCAN。如果你有NonClustered Index,那么Jonathan的方法将会执行SEEK而不是SCAN,这在性能方面会很好。
让我试着解释为什么这是一个示例,如下表所示:为便于使用,我没有考虑两个谓词部分和城市,而是我只考虑城市。
考虑员工见下表:
CREATE TABLE [dbo].[Employee](
[EmployeeId] [int] NULL,
[EmployeeName] [varchar](20) NULL,
[Dept] [varchar](15) NULL,
[city] [varchar](15) NULL
) ON [PRIMARY]
GO
--Creating Clustered Index on Id
CREATE CLUSTERED INDEX [CI_Employee_EmployeeId] ON [dbo].[Employee] ([EmployeeId] ASC)
--Loading Data
加载数据采样
Insert into Employee
Select top (10000) EmployeeId = Row_Number() over (order by (Select NULL))
,EmployeeName = Concat ('Name ',Row_Number() over (order by (Select NULL)))
,Dept = Concat ('Dept ',(Row_Number() over (order by (Select NULL))) % 50)
,City = Concat ('City ',Row_Number() over (order by (Select NULL)))
from master..spt_values s1, master..spt_values s2
现在执行简单的查询与正常断言:
Declare @city varchar(15) = 'City 1500'
Select * from Employee where city = @city
--It Does Clustered Index Scan
现在的城市建立一个非聚集索引
--Now adding Index on City
Create NonClustered Index NCI_Employee_City on dbo.Employee (city)
Declare @city varchar(15) = 'City 1500'
Select * from Employee where city = @city
--It Does Index Seek
现在来到你的ISNULL函数 因为它迫使每个城市功能,它使用SCAN如下
Declare @city varchar(15) = 'City 1500'
Select * from Employee where city = isnull(@city, City)
go
Declare @city varchar(15) = 'City 1500'
Select * from Employee where city is null or city = @city
如果您查看整个百分比,IsNull函数需要更多。
因此,如果你有一个索引,所有这些将是有用的,否则它将被扫描。