【问题标题】:nhibernate query performance休眠查询性能
【发布时间】:2009-07-21 05:03:25
【问题描述】:

我决定在现有应用程序上测试 nhibernate(将 linq 替换为 sql),到目前为止我看到的结果很糟糕。希望这里有人能指出我正确的方向。

我的配置:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
        <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">{my connection string here}</property>
        <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
        <property name="adonet.batch_size">10</property>
        <property name="show_sql">false</property>           
        <property name="use_outer_join">true</property>
        <property name="command_timeout">60</property>
        <property name="query.substitutions">false</property>            
    </session-factory>
</hibernate-configuration>

领域类:

public class Code
{
    public virtual Guid CodeId { get; set; }
    public virtual string CodeValue { get; set; }
    public virtual Guid EntryId { get; set; }
}

映射xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SweepstakesWeb" namespace="SweepstakesWeb.Domain">
    <class name="Code" table="Codes">
        <id name="CodeId">
            <generator class="guid.comb"/>
        </id>
        <property name="CodeValue" length="20" />
        <property name="EntryId" />
    </class>
</hibernate-mapping>

当我运行测试时,我看到了这个:

对于以下查询:

SELECT this_.CodeId as CodeId0_0_, this_.CodeValue as CodeValue0_0_, this_.EntryId as EntryId0_0_ FROM Codes this_ WHERE this_.CodeValue = N'3734872FVD'

我明白了:

StmtText
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  |--Nested Loops(Inner Join, OUTER REFERENCES:([this_].[CodeID]) OPTIMIZED)
       |--Index Scan(OBJECT:([Codes].[ix_codes_code] AS [this_]),  WHERE:(CONVERT_IMPLICIT(nvarchar(20),[Codes].[CodeValue] as [this_].[CodeValue],0)=N'3734872FVD'))
       |--Clustered Index Seek(OBJECT:([Codes].[PK__Codes__3493CFA7] AS [this_]), SEEK:([this_].[CodeID]=[Codes].[CodeID] as [this_].[CodeID]) LOOKUP ORDERED FORWARD)

如果我像这样手动将参数更改为 varchar(删除 N 前缀):

SELECT this_.CodeId as CodeId0_0_, this_.CodeValue as CodeValue0_0_, this_.EntryId as EntryId0_0_ FROM Codes this_ WHERE this_.CodeValue = '3734872FVD'

我明白了:

StmtText
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  |--Nested Loops(Inner Join, OUTER REFERENCES:([this_].[CodeID]) OPTIMIZED)
       |--Index Seek(OBJECT:([Codes].[ix_codes_code] AS [this_]), SEEK:([this_].[CodeValue]='3734872FVD') ORDERED FORWARD)
       |--Clustered Index Seek(OBJECT:([Codes].[PK__Codes__3493CFA7] AS [this_]), SEEK:([this_].[CodeID]=[Codes].[CodeID] as [this_].[CodeID]) LOOKUP ORDERED FORWARD)

请注意,使用 varchar 参数值而不是 nvarchar,我会得到一个索引搜索。使用 nvarchar,我得到一个索引扫描。列类型是 varchar(20)。显然,正在进行的隐式转换导致完全扫描而不是搜索。

  1. 为什么隐式转换需要扫描而不是查找?
  2. 为什么 nhibernate 默认使用 nvarchar,如何告诉它使用 varchar?

【问题讨论】:

    标签: sql-server nhibernate


    【解决方案1】:

    【讨论】:

    • 链接不再有效,我也遇到了同样的问题。你能给出更完整的答案吗?
    • 如果我没记错的话,解决方案是将所有列设为 nvarchar。 NHibernate 自动将 System.String 映射到 nvarchar,当与 varchar 比较时,它不能使用索引查找。
    • 查看此链接以获得很好的解释:dylanbeattie.blogspot.com/2010/02/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2016-04-22
    相关资源
    最近更新 更多