2009-07-21 84 views
2

我決定在現有應用程序上測試nhibernate(將linq替換爲sql),到目前爲止我看到了糟糕的結果。希望有人能在這裏指出我的正確方向。nhibernate查詢性能

我的配置:

<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參數值instea d的nvarchar,我得到一個索引查找。用nvarchar,我得到一個索引掃描。列類型是varchar(20)。顯然,有一個隱式轉換正在導致全面掃描而不是查找。

  1. 爲什麼隱式轉換需要掃描而不是查找?
  2. 爲什麼nhibernate默認使用nvarchar,我該如何告訴它使用varchar?

回答