FreeSql icon indicating copy to clipboard operation
FreeSql copied to clipboard

Ado.Query 使用参数化查询非常缓慢

Open HydrogenDeuterium opened this issue 8 months ago • 7 comments

问题描述及重现代码:

public static readonly IFreeSql fsql = new FreeSqlBuilder()
.UseConnectionString(
DataType.Oracle,
dBUtility.Get_DB_ConnectionString(...)
)
.UseAutoSyncStructure(false)
.Build(); //请务必定义成 Singleton 单例模式

private const string sql = @"select c1,i2,c3 from t WHERE cond =:cond ";
var result2 = fsql.Ado.Query<(string, int, string)>(sql, new {cond=cond})
                 .ToList();

使用参数化查询,查询消耗5秒以上,数据库工具中手工查询,消耗0.004秒。将参数化查询改为手工拼接sql,可以秒出结果

数据库版本

Oracle 10

安装的Nuget包

3.5.208

.net framework/. net core? 及具体版本

.net framework 4.6.2

HydrogenDeuterium avatar Jun 24 '25 09:06 HydrogenDeuterium

这是数据库问题,按说从数据库使用参数化查询能复现,可能绑定参数使用了错误的查询计划导致的,可以让DBA分析下。

hd2y avatar Aug 28 '25 03:08 hd2y

检查参数类型,比如 nvarvhar 和 varchar 差距巨大

2881099 avatar Aug 29 '25 01:08 2881099

这是数据库问题,按说从数据库使用参数化查询能复现,可能绑定参数使用了错误的查询计划导致的,可以让DBA分析下。

找DBA 看过了,没看出什么有意义的结论。相同的查询语句和绑定参数我 用 python3.9-cx_Oracle 试过查询也是正常的。 是否有什么其他的日志 捕捉参数什么的是我可以提供的?

HydrogenDeuterium avatar Oct 03 '25 12:10 HydrogenDeuterium

aop.commandbefore 事件,把 Command 对象的内容打印出来,包括Parameters

2881099 avatar Oct 04 '25 11:10 2881099

使用以下输出语句进行输出:

            dcprod.Aop.CommandBefore+=(s, e) => {
                Console.WriteLine($"SQL: {e.Command.CommandText}");
                foreach (dynamic param in e.Command.Parameters) {
                    Console.WriteLine($"ParameterKey: {param.ParameterName} ParameterValue {param.Value}");
                }
            };

结果如下:

SQL: select SUM(LOT_QTY) FROM dcdm.WIP_LOT_MASTER wlm WHERE CONTROL_LOT = :control
ParameterKey: :control ParameterValue RTCG41N5N9

好像看不出什么问题

HydrogenDeuterium avatar Nov 07 '25 07:11 HydrogenDeuterium

仔细研究了一下应该是传参的问题,程序用的参数类型是NVARCHAR2,但是表里面的字段是Varchar2的,导致不走索引。 请问下有什么办法指定传参为varchar吗?

HydrogenDeuterium avatar Nov 07 '25 07:11 HydrogenDeuterium

Ado.CommandFluent().WithParameter(...

2881099 avatar Nov 09 '25 16:11 2881099