dotnetcore / SmartSql

SmartSql = MyBatis in C# + .NET Core+ Cache(Memory | Redis) + R/W Splitting + PropertyChangedTrack +Dynamic Repository + InvokeSync + Diagnostics
https://smartsql.net/
Apache License 2.0
1.1k stars 222 forks source link

使用In时,当集合元素过多时,执行效率会大幅降低 #214

Open xiangxiren opened 2 years ago

xiangxiren commented 2 years ago

在我实际应用中,In中的元素个数会有几百个甚至也许会更多。目前SmartSql中实现时,有多少个元素就会定义多少个参数,类似:@Ids_0,@Ids_1,@Ids_2…… 。这样执行效率会很低。相同条件的查询,使用EFCore时,它会把元素直接拼接到SQL中,不会使用参数化,类似 where id in (1,2,3……)。通过我的对比,EFCore这样的做法会有更好的性能。因此,我建议SmartSql对In也这样处理,不再使用参数化。

XiaoHeitu commented 1 year ago

参数化有一个优势是天生可防御sql注入。这个问题可能需要一起考虑。

xiangxiren commented 1 year ago

https://github.com/dotnetcore/SmartSql/blob/56209435e1a7f5c2b9d674f948750ee78aceca90/src/SmartSql/Configuration/Tags/SqlText.cs#L44-L50

通过集合的第一个元素判断集合元素类型,如果是int,long等数字类型就直接拼接,bool类型转换成0/1再拼接,字符串用'包围,日期转换成字符串再用'包含后拼接,应该不会有注入问题

xuejmnet commented 1 year ago

efcore是判断你是常量还是变量如果是变量那么就是参数化如果是常量才是直接在sql中

xiangxiren commented 1 year ago

efcore是判断你是常量还是变量如果是变量那么就是参数化如果是常量才是直接在sql中

我这项目里有很多查询都依赖于用户当前有权限的组织,所以组织每次都是通过调接口获取的。然后生成的查询里,组织Id都是直接在SQL里,并没有参数化。