如何对 SQL Server 中的左连接表进行多个条件全文搜索?
-
09-06-2019 - |
题
我有一个最初看起来像这样的查询:
select c.Id, c.Name, c.CountryCode, c.CustomerNumber, cacc.AccountNumber, ca.Line1, ca.CityName, ca.PostalCode
from dbo.Customer as c
left join dbo.CustomerAddress as ca on ca.CustomerId = c.Id
left join dbo.CustomerAccount as cacc on cacc.CustomerId = c.Id
where c.CountryCode = 'XX' and (cacc.AccountNumber like '%C17%' or c.Name like '%op%'
or ca.Line1 like '%ae%' or ca.CityName like '%ab%' or ca.PostalCode like '%10%')
在包含 90,000 条记录的数据库上,执行此查询大约需要 7 秒(显然所有连接和点赞都很费力)。
我一直在尝试找到一种方法,通过对相关列进行全文搜索来缩短查询执行时间。但是,我还没有看到像这样具有三个表连接的全文搜索示例,特别是因为我的连接条件不是搜索词的一部分。
有没有办法在全文搜索中做到这一点?
@大卫
是的,Id 上有索引。
我尝试过在 CustomerAddress 内容(城市名称、邮政编码等)上添加索引,并将查询时间缩短到 3 秒,但我仍然发现对于这样的事情来说太慢了。
请注意,所有文本字段(id 除外)都是 nvarchar,而 Line1 是 nvarchar 1000,因此这可能会影响速度,但仍然如此。
解决方案
通过查询分析器运行它并查看查询计划是什么。我的猜测是双根(即%ae%) 搜索导致它在查找匹配行时执行表扫描。双根搜索本质上很慢,因为您通常无法使用任何类型的索引来匹配它们。
其他提示
笔记:这并不是真正的答案,只是试图澄清实际上可能导致性能问题的原因。
90,000 条记录确实是一个相当小的数据集,而且查询也相对简单,只有两个 join。您是否有 CustomerAddress.CustomerId 和 CustomerAccount.CustomerId 索引?这似乎比 where 条件 LIKE 谓词更有可能导致性能问题。您通常是否同时搜索所有这些列上的匹配项?
我同意大卫的建议。您可能想要检查 RDBMS 如何执行查询(例如,通过表扫描或使用索引)。
一项快速检查是仅对涉及文本搜索的查询部分进行计时。像这样的东西:
SELECT ca.Line1, ca.CityName, ca.PostalCode
FROM CustomerAddress as ca
WHERE ca.CustomerId = <some id number>
AND (ca.Line1 LIKE '%ae%' OR ca.CityName LIKE '%ab%' OR ca.PostalCode LIKE '%10%');
如果这需要很长时间,那么 LIKE
s 是问题(一次从 OR
编辑行以查看是否只有其中一列导致速度减慢)。如果速度很快,那么连接就值得怀疑。
您也可以为 CustomerAccount 表编写类似的查询。