Performance 查找以键结尾的记录的最快方法
我正在寻找一种最佳的方法来搜索数以百万计的记录,这些记录包含保存为varchar列的序列号,该列以指定的字符串键结尾 我使用的是EndsWith,但是如果发送多个查询,则性能相当差 有更好的方法吗 编辑: 由于搜索键的长度可变,所以我无法创建保存序列号截止值的列。然而,我已经使用Substring和Equals与EndsWith进行了一些测试,我已经将执行速度降低到EndsWith的40%Performance 查找以键结尾的记录的最快方法,performance,linq,entity-framework,Performance,Linq,Entity Framework,我正在寻找一种最佳的方法来搜索数以百万计的记录,这些记录包含保存为varchar列的序列号,该列以指定的字符串键结尾 我使用的是EndsWith,但是如果发送多个查询,则性能相当差 有更好的方法吗 编辑: 由于搜索键的长度可变,所以我无法创建保存序列号截止值的列。然而,我已经使用Substring和Equals与EndsWith进行了一些测试,我已经将执行速度降低到EndsWith的40% 但我仍在寻找更好的解决方案:)不幸的是,在大多数数据库+,搜索以特定模式结尾的字符串很困难,因为搜索字符串
但我仍在寻找更好的解决方案:)不幸的是,在大多数数据库+,搜索以特定模式结尾的字符串很困难,因为搜索字符串后缀不能使用索引。这会导致全表扫描,这在具有数百万行的表上可能会很慢 如果数据库支持反向索引,请为字符串键列添加一个索引;否则,您可以通过模拟反向索引来提高性能:
- 添加一列,用于反向存储字符串键
- 如果您的RDBMS支持,请为反向密钥添加一个
- 否则,定义一个从键列填充反转列的触发器
- 在反向列上创建索引
- 通过输入要查找的反向后缀,使用反向列进行搜索
key
-----------
01-02-3-xyz
07-12-8-abc
那么扩充表就有了
key rev_key
----------- -----------
01-02-3-xyz zyx-3-20-10
07-12-8-abc cba-8-21-70
您对的搜索以(key,'3-xyz')结束
将要求以(rev_key,'zyx-3')开始
。由于字符串索引通过前缀加快查找速度,“以开头”查找速度会快得多
+一个值得注意的例外是Oracle,它专门为这种情况提供了支持。不幸的是,在大多数数据库+,搜索以特定模式结尾的字符串很困难,因为搜索字符串后缀不能使用索引。这会导致全表扫描,这在具有数百万行的表上可能会很慢 如果数据库支持反向索引,请为字符串键列添加一个索引;否则,您可以通过模拟反向索引来提高性能:
- 添加一列,用于反向存储字符串键
- 如果您的RDBMS支持,请为反向密钥添加一个
- 否则,定义一个从键列填充反转列的触发器
- 在反向列上创建索引
- 通过输入要查找的反向后缀,使用反向列进行搜索
key
-----------
01-02-3-xyz
07-12-8-abc
那么扩充表就有了
key rev_key
----------- -----------
01-02-3-xyz zyx-3-20-10
07-12-8-abc cba-8-21-70
您对的搜索以(key,'3-xyz')结束
将要求以(rev_key,'zyx-3')开始
。由于字符串索引通过前缀加快查找速度,“以开头”查找速度会快得多
+一个值得注意的例外是Oracle,它专门为这种情况提供服务。您的底层数据库是什么?可能是SQL server。。。但是什么版本(2008、2008r2、2012)和版本(express、standard、enterprise…)?SQL Server 2008 R2 express是我正在使用的数据库,我正在使用Entity Framework 5.0。也许可以帮助您。您的基础数据库是什么?可能是SQL Server。。。但是什么版本(2008、2008r2、2012)和版本(express、standard、enterprise…)?SQL Server 2008 R2 express是我正在使用的数据库,我使用的是Entity Framework 5.0。也许可以帮助您。我将尝试您的解决方案,并在追溯生成反向密钥后立即看到实际性能的改进。我喜欢这个想法:)不幸的是,这并没有带来性能优化。速度与EndsWith保持完全相同。太糟糕了,听起来像是聪明的解决方案:(@BarisaPuter这很奇怪。你能尝试使用
rev_键,比如'zyx-3%'
而不是以开始吗?如果实现正确,这将提高性能。@OP请发布你的查询、SQL和执行计划。我完全按照这里指定的方式实现了。我使用的是EF,所以我不是编写精确的查询,而是使用LINQ syntax、 使用子字符串而不是EndsWith,我成功地获得了改进。反向序列号和STARTSWWITH没有任何区别。这很可能是因为序列号从不超过10个字符。我将尝试您的解决方案,并在生成反向密钥后立即看到实际性能的改进ly.我喜欢这个想法:)不幸的是,这没有产生任何性能优化。速度与EndsWith完全相同。太糟糕了,听起来像是智能解决方案:(@BarisaPuter这很奇怪。你能尝试使用rev_键,比如'zyx-3%'
而不是以开始吗?如果实现正确,这将提高性能。@OP请发布你的查询、SQL和执行计划。我完全按照这里指定的方式实现了。我使用的是EF,所以我不是编写精确的查询,而是使用LINQ syntax、 使用子字符串而不是EndsWith,我成功地获得了改进。反向序列号和StartsWith没有任何区别。很可能是因为序列号从不超过10个字符。