在 SQL 服务器中查找电子邮件地址
Email address lookup in SQL Server
我们有一个庞大的订阅者数据库,并根据 nvarchar(100)
类型的电子邮件地址进行查找。有时会超时,可能是扫描量大的缘故。
var existingEmails =
_subscriptionsRepository.DataContext
.Subscriptions
.Where(q => q.Email != null &&
q.Email.ToLower().Equals(model.Email.ToLower()))
.ToList();
我想对此进行改进,但厌倦了某些选项。如果它的索引可以,我可以在需要时处理额外的存储,或者计算列来获取域部分。根据数十万个电子邮件地址查找一行的快速方法是什么?
是的,这正是索引的用途。添加索引。但是:要使索引以最佳方式工作,它需要是索引中存储的值的相等(或至少是范围)过滤器; LCASE(Foo)
/LOWER(Foo)
等不符合条件。假设您的数据库 运行 处于区分大小写模式,那么在存储数据时最好以规范化形式(小写或其他)存储数据 ,然后对您要搜索的数据执行相同的规范化,让您只需对数据库使用相等性测试,即
var normalizedEmail = YourNormalizationMethodHere(model.Email);
var matches = _subscriptionsRepository.DataContext.Subscriptions.Where(
q => q.NormalizedEmail != null && q.NormalizedEmail == normalizedEmail);
(但即使只是将数据 放在索引 中也可以提高性能,即使使用 LCASE
/LOWER
之类的函数也是如此,因为它可以减少需要阅读页数)
@MarcGravelli 显然是对的。
很难确定,但我猜你的查询的问题在于它必须将数十万个电子邮件地址转换为小写,然后将它们与你的搜索词进行比较。转换的成本可能比搜索本身的成本更高。
正如 Marc 所说,在存储数据之前对数据进行规范化好得多。
如果这不可能,您可以引入一个具有地址的小写版本的计算列,并向该列添加索引。然后您可以对该列进行搜索。
当然,这有点麻烦,可能会导致维护困难,但这可能是一个短期解决方案。
我们有一个庞大的订阅者数据库,并根据 nvarchar(100)
类型的电子邮件地址进行查找。有时会超时,可能是扫描量大的缘故。
var existingEmails =
_subscriptionsRepository.DataContext
.Subscriptions
.Where(q => q.Email != null &&
q.Email.ToLower().Equals(model.Email.ToLower()))
.ToList();
我想对此进行改进,但厌倦了某些选项。如果它的索引可以,我可以在需要时处理额外的存储,或者计算列来获取域部分。根据数十万个电子邮件地址查找一行的快速方法是什么?
是的,这正是索引的用途。添加索引。但是:要使索引以最佳方式工作,它需要是索引中存储的值的相等(或至少是范围)过滤器; LCASE(Foo)
/LOWER(Foo)
等不符合条件。假设您的数据库 运行 处于区分大小写模式,那么在存储数据时最好以规范化形式(小写或其他)存储数据 ,然后对您要搜索的数据执行相同的规范化,让您只需对数据库使用相等性测试,即
var normalizedEmail = YourNormalizationMethodHere(model.Email);
var matches = _subscriptionsRepository.DataContext.Subscriptions.Where(
q => q.NormalizedEmail != null && q.NormalizedEmail == normalizedEmail);
(但即使只是将数据 放在索引 中也可以提高性能,即使使用 LCASE
/LOWER
之类的函数也是如此,因为它可以减少需要阅读页数)
@MarcGravelli 显然是对的。
很难确定,但我猜你的查询的问题在于它必须将数十万个电子邮件地址转换为小写,然后将它们与你的搜索词进行比较。转换的成本可能比搜索本身的成本更高。
正如 Marc 所说,在存储数据之前对数据进行规范化好得多。
如果这不可能,您可以引入一个具有地址的小写版本的计算列,并向该列添加索引。然后您可以对该列进行搜索。
当然,这有点麻烦,可能会导致维护困难,但这可能是一个短期解决方案。