【问题标题】:A cleaner implementation rather than using LIKE更简洁的实现,而不是使用 LIKE
【发布时间】:2011-12-06 10:48:29
【问题描述】:

我有一个表格,其中包含用分号分隔的电子邮件域。

Domain
------
gmail.com;googlemail.com
hotmail.com;hotmail.co.uk;live.co.uk

我目前正在运行以下 SQL:

SELECT [Id]
  FROM [DomainGroup]
 WHERE [Domain] LIKE '%' + (SELECT RIGHT('anemail@gmail.com', CHARINDEX('@', REVERSE('anemail@gmail.com')) - 1)) + '%'

虽然这行得通,但我认为从性能和可读性两方面来看,使用 PATINDEX 可能会更好。电子邮件地址实际上是一个变量,但我将其放入以显示我想要实现的目标。

【问题讨论】:

  • 为什么不把列规范化成一个单独的表呢?您当前的类似方法会说接受hotmail.com for neil@hotmail.co,这对您的实施可能没什么大不了,但值得指出。

标签: performance sql-server-2008


【解决方案1】:

我认为PATINDEXLIKE 的性能优势充其量是ambiguous,尤其是在您的情况下,因为将分隔值标准化为索引列中的各个行会比其他任何东西都提供更多的性能提升.

如果您无法更改设计并想使用PATINDEX,那么我会预先计算模式;

declare @emaildomain varchar(128) = 'anemail@gmail.com'
set @emaildomain = '%;' + stuff(@emaildomain, 1, charindex('@', @emaildomain), '')  + ';%'

然后在 where 子句中使用它;

where patindex(@emaildomain, ';' + [Domain] + ';') > 0

(我用; 分隔符填充,所以aaa@bbb.comaaabbb.com; 不匹配)

【讨论】:

  • 使用这个PATINDEX,我必须以;开始域?
  • LIKE 相同; %aaa.com 将匹配 xxxaaa.com;bbb.com 中的 xxxaaa.com - 添加 ; 确保测试是 ;xxxaaa.com;bbb.com; 中的 %;aaa.com;(即在这种情况下不匹配)
【解决方案2】:

您是否考虑过使用全文搜索?

创建索引后,查询将如下所示:

SELECT [Id] FROM [DomainGroup] WHERE CONTAINS ([Domain], 'gmail.com')

【讨论】:

    猜你喜欢
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    相关资源
    最近更新 更多