First, a simple example to describe my problem.
Model
public class User
{
public virtual String UserID { get; set; }
public virtual String UserName { get; set; }
public virtual DateTime LastLoginTime { get; set; }
}
Mapping
<id name="UserID" type="AnsiString">
<column name="p_UserID_vc" length="20"></column>
<generator class="assigned"/>
</id>
<property name="UserName" column="UserName_vc" type="AnsiString">
<property name="LastLoginTime" column="LastLoginTime_d" type="DateTime">
table
create table T_User
(
p_userid_vc VARCHAR2(20) not null,
username_vc VARCHAR2(50),
lastlogintime_d DATE,
)
Now ,there are one million users in this table. I create a oracle index in LastLoginTime. I use query like this:
var list = Responsity<User>.Where(q => q.LastLoginTime <= DateTime.Now &&
q.LastLoginTime >= DateTime.Now.AddDays(-7));
I use Nhibernate Profile to watchout the real sql string:
select t.p_UserID_vc
from T_User t
where t.lastlogintime_d >= TIMESTAMP '2012-03-19 16:58:32.00' /* :p1 */
and t.lastlogintime_d <= TIMESTAMP '2012-03-26 16:58:32.00' /* :p2 */
It didn’t use the index. I think it should use ‘to_date’ ,so that it could use the index. How to config the mapping file?
There are a few reasons why it might not be using your index:
The datatype of
LastLoginTimeis aDATE, but the parameters areTIMESTAMPs, so it might be implicitly converting the column to a timestamp, which would mean it cannot use the index.The Cost-Based-Optimizer (CBO) might be using statistics which indicate that using the index would be less efficient than not using it. For example, there might be very few rows in the table, or a histogram might tell the CBO that a large number of rows match the date range you’re querying on. It’s not uncommon for full table scans to outperform queries that use indexes.
Perhaps the statistics on the table are out-of-date, causing the CBO to make inaccurate estimates.
Do an explain plan on your query to determine what the cause is.
Note: the plan for a query that uses literal values (e.g.
TIMESTAMP '...') could very well be different to that for a query that uses bind variables (e.g.p1andp2). Run the explain plan for the query that is actually being executed.