我正在根据某个nvarchar
列的第一个字母而不是通常的列创建结果分页,这通常会在结果数量上进行分页。
我是否面临使用LIKE
运算符或相等(=
)运算符过滤结果的挑战。
select *
from table
where name like @firstletter + '%'
VS
select *
from table
where left(name, 1) = @firstletter
我尝试在网上搜索两者之间的速度比较,但很难找到任何结果,因为大多数搜索结果都与LEFT JOINs
而非LEFT
功能相关。
答案 0 :(得分:13)
“Left”vs“Like” - 在执行索引时,应始终使用“Like”,因为“Like”不是函数,因此可以使用您可能拥有的任何索引数据。
另一方面,“左”是功能,因此不能使用索引。 This web page描述了一些示例的使用差异。这意味着SQL服务器必须为每个返回的记录评估函数。“子串”和其他类似的功能也是罪魁祸首。
答案 1 :(得分:8)
您最好的选择是衡量实际生产数据的表现,而不是试图猜测(或询问我们)。这是因为性能有时可能取决于您正在处理的数据,虽然在这种情况下似乎不太可能(但我不知道那么,因此您应该检查)。
如果这是一个你会做很多的查询,你应该考虑另一个(索引)列,它包含name
的小写首字母,并由插入/更新触发器设置。
这将以最小的存储增加为代价,使这个查询的速度非常快:
select * from table where name_first_char_lower = @firstletter
这是因为大多数数据库的读取频率远远高于写入数据库,这将在所有读取中分摊计算成本(仅针对写入)。
它引入了冗余数据,但只要您理解(并在此建议中减轻)后果并且需要额外性能,就可以为性能做到这一点。
答案 2 :(得分:4)
我有一个类似的问题,并对两者都进行了测试。这是我的代码。
where (VOUCHER like 'PCNSF%'
or voucher like 'PCLTF%'
or VOUCHER like 'PCACH%'
or VOUCHER like 'PCWP%'
or voucher like 'PCINT%')
在1分51秒内返回1434行。
VS
where (LEFT(VOUCHER,5) = 'PCNSF'
or LEFT(VOUCHER,5)='PCLTF'
or LEFT(VOUCHER,5) = 'PCACH'
or LEFT(VOUCHER,4)='PCWP'
or LEFT (VOUCHER,5) ='PCINT')
在1分27秒内返回1434行
左边的数据更快5.另外,我的整体查询确实会触及一些索引。
答案 3 :(得分:1)
当搜索列包含索引时,我总是建议使用like运算符。我在生产环境中使用table_name中的select count(column_name)测试了上述查询,其中left(column_name,3)='AAA'或left(column_name,3)='ABA'或...最多9个OR子句。我的计数显示7301477条记录,左边4秒,类似1秒,其中column_name像'AAA%'或Column_Name像'ABA%'或...最多9条条款。
在where子句中调用函数不是最佳实践。请参阅http://blog.sqlauthority.com/2013/03/12/sql-server-avoid-using-function-in-where-clause-scan-to-seek/
答案 4 :(得分:0)
您可以使用public class JsonItemProcessor implements ItemProcessor<Map<String, Object>, List<Json>> {
private ObjectMapper mapper = new ObjectMapper();
private static final Logger logger = LoggerFactory.getLogger(JsonItemProcessor.class);
public List<Json> process(Map<String, Object> jsonItem) throws Exception {
JsonNode jsonNode = mapper.valueToTree(jsonItem);
return parseJsonItems(jsonNode);
}
代替EF.Functions.Like(columnName, searchString + "%")
,并且在生成的SQL中仅获得LIKE函数,而不是所有这些“左”疯狂!
根据您的需求,您可能需要预处理searchString。
另请参阅https://github.com/aspnet/EntityFrameworkCore/issues/7429
此功能在实体框架(非核心)columnName.startsWith(...)
中不存在,因此我不确定如何为EF6执行此功能。