使用 DateTime 类型参数的 Dapper 查询速度慢?

Posted

技术标签:

【中文标题】使用 DateTime 类型参数的 Dapper 查询速度慢?【英文标题】:Dapper query slow with DateTime type parameter? 【发布时间】:2015-02-10 02:53:53 【问题描述】:

例如1

string sql="select * from A where time>=:begin_time and time<=:end_time";

DateTime bt = new DateTime(2013, 04, 19);
DateTime et = new DateTime(2013, 04, 20, 15, 0, 0);
conn.Query<Object>(sql,new begin_time=bt,end_time=et).ToList()

查询慢,时间为00:00:02.2142132


例如.2

string sql="select * from A where time>=to_date(:begin_time,'yyyy-mm-dd      hh24:mi:ss') and time<to_date=(:end_time,'yyyy-mm-dd hh24:mi:ss')";

conn.Query<Object>(sql,new begin_time="2013-04-19 0:00:00",end_time="2013-04-20 15:00:00").ToList()

查询速度很快,时间为00:00:00.4604229


以下是一个新的测试用例。数据库中的所有测试记录数均为 39。

group1:使用 Oracle.ManagedDataAccess

test1: 00:00:01.9456767。使用 dapper 并且 datetime 是 datetime 类型(eg1.:begin_time)

test2: 00:00:00.6667549。使用 dapper 和 datetime 是字符串类型(eg2.to_date(:begin_time,format) )

test3: 00:00:01.8552286。使用 ado.net/OracleCommand/OracleDataAdapter 和 datetime 是 datetime 类型(eg1.:begin_time)

test4: 00:00:00.0592419。使用 ado.net/OracleCommand/OracleDataAdapter 和 datetime 是字符串类型(eg2.to_date(:begin_time,format))


group2:使用 System.Data.OracleClient

test5: 00:00:00.0184799。使用 dapper 并且 datetime 是 datetime 类型(eg1.:begin_time)

test6: 00:00:00.1158088。使用 dapper 和 datetime 是字符串类型(eg2.to_date(:begin_time,format) )

test7: 00:00:00.0193022。使用 ado.net/OracleCommand/OracleDataAdapter 和 datetime 是 datetime 类型(eg1.:begin_time)

test8: 00:00:00.0185583。使用 ado.net/OracleCommand/OracleDataAdapter 和 datetime 是字符串类型(eg2.to_date(:begin_time,format))

我发现如果使用 System.Data.OracleClient 两种方式都很快。只用Oracle.ManagedDataAccess,eg1慢,eg2快。

可能是 Oracle.ManagedDataAccess 的原因。

【问题讨论】:

这是一致的行为吗?或者,当您运行第二个查询时,您是否可能会看到缓存的影响?您是否看到两个查询的不同计划? 缓存为假,eg.1总是很慢,eg.2总是很快。 顺便说一句,我的数据库是oracle。 您是否对这两个查询有不同的计划? eg.2 计划是 :!Valid Xhtml.. ge1 计划我拿不到。 【参考方案1】:

我在使用 Oracle.ManagedDataAccess 时遇到了类似的问题,我发现 DateTime 参数在查询中被转换为 Timestamp。如果您的时间列是Date 而不是Timestamp,Oracle 会隐式将其转换为Timestamp,并且它将无法使用该列上的任何索引。

尝试将您的查询重写为:

select * from A where time>=cast(:begin_time as date) and time<=:cast(end_time as date)

看看这是否能提高性能。

【讨论】:

【参考方案2】:

试试看。

SqlMapper.AddTypeMap(typeof(DateTime), DbType.Date);

因为 Dapper 默认设置 typeof(DateTime) 等于 DbType.DateTime, 但 DbType.DateTime 默认等于 OracleDbType.TimeStamp, 所以可以设置DbType.Date映射OracleDbType.Date。

【讨论】:

这个解决方案非常适合我!请记住在程序开始时应用它。似乎不可能在查询到 db 之后添加 TypeMap。谢谢沃尔特! 要添加的代码是什么,是您帖子的第一行还是最后一行。这个答案很难真正理解你的意思?

以上是关于使用 DateTime 类型参数的 Dapper 查询速度慢?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dapper 中获取正确的 DateTime

将 .net DateTime 的 Dapper 映射更改为使用 DbType DateTime2 并再次恢复它

Dapper - <>f__AnonymousType.....类型的成员不能用作参数值

Dapper入门教程——Dapper Query查询

Dapper系列 作者:懒懒的程序员一枚

在 C# 中使用 Dapper 将数据发送到 RECORD 类型的 PL/SQL 脚本变量会更好吗