我有以下查询:
DECLARE @CompanyId bigint
DECLARE @SearchText nvarchar(4000)
SET @CompanyId=160
SET @SearchText='%02863%'
SELECT j.Id FROM Job (NOLOCK) j WHERE (j.Deleted = 0 AND j.CompanyId = @CompanyId)
AND (j.Name LIKE @SearchText OR j.DisplayId LIKE @SearchText OR j.ClaimNumber LIKE @SearchText)
UNION SELECT j.Id FROM Job (NOLOCK) j INNER JOIN Address (NOLOCK) a ON a.Id = j.AddressId
WHERE j.Deleted = 0 AND j.CompanyId = @CompanyId
AND a.SearchAddress LIKE @SearchText
UNION SELECT j.Id FROM Job (NOLOCK) j INNER JOIN Contact (NOLOCK) c ON c.Id = j.CustomerId
WHERE j.Deleted = 0 AND j.CompanyId = @CompanyId
AND c.SearchName LIKE @SearchText
有时需要超过10秒才能运行。
我们的DB非常小,而且我认为它不应该花这么长时间,我想知道我是否正确地制定了这个查询或者我是否应该更改它?
从我读过的内容来看,我认为实施全文检索不会有太大帮助,因为这些都是直接比较,对吗?
另外,鉴于此查询,我希望它只搜索属于companyId = @ companyId和deleted = 0的作业的地址和联系人?或者它会搜索整个数据库中的所有地址和联系人,然后根据工作标准进行过滤?
答案 0 :(得分:1)
您可能想要考虑的另一件事是将所有选择组合成一个语句。现在正在发生的事情是你正在进行三次完整的索引扫描,然后过滤掉任何重复的(使用union)。在这种情况下,通过表格并在查询中使用“或”可能会更快。
为了回答您的上一个问题,现在使用完整的索引扫描,Sql server在逐行的基础上运行得更多。因此,它将查看第一个数据点。如果j.deleted = 0,则sql将继续评估您包含的下一个条件。因此,它会查看companyId = @companyId。如果是这样,它会继续检查下一个条件。
将查询更改为执行搜索可以让sql更快更容易地查找您要查找的内容。
DECLARE @CompanyId bigint
DECLARE @SearchText nvarchar(4000)
SET @CompanyId=160
SET @SearchText='%02863%'
SELECT j.Id
FROM Job (NOLOCK) j
WHERE j.Deleted = 0
AND j.CompanyId = @CompanyId
AND ( j.Name LIKE @SearchText
OR j.DisplayId LIKE @SearchText
OR j.ClaimNumber LIKE @SearchText
OR (exists select 1
From address (nolock a)
Where a.id = j.addressid
and a.SearchAddress like @SearchText)
or (exists select 1
From contact (nolock) c
Where c.id=j.customerid
and c.SearchName like @SearchText)
)
答案 1 :(得分:0)
@SearchText='%02863%'
将导致完整的索引扫描,因为它正在索引中的任何位置搜索此字符串。如果搜索字符串类似于' 02863%',它可以使用索引搜索并且更有效率,因为它有一些东西可以开始。
如果您可以发布执行计划,那将是最有帮助的。