java - Hibernate SQL In clause making CPU usage to 100% -
in java application using sql server , hibernate3 ejb
. when tried execute select query with in clause
, db server cpu usage reaches 100%. when tried run same query in sql management studio
, query running without cpu spikes. application server , db server 2 different machines. table has following schema,
create table student_table ( student_id bigint not null identity , class_id bigint not null , student_first_name varchar(100) not null , student_last_name varchar(100) , roll_no varchar(100) not null , primary key (student_id) , constraint uk_studentunique_1 unique (class_id, roll_no) );
the table contains around 1000k records. query
select student_id student_table roll_no in ('a101','a102','a103',.....'a250');
in clause contains 250 values, when tried run above query in sql management studio result retrieved within 1 seconds , without cpu spikes. when tried run same query through hibernate cpu spikes reaches 100% around 60 seconds , result retrieved around 60 seconds. hibernate query is,
criteria studentcriteria = session.createcriteria(studentto.class); studentcriteria.add(restrictions.in("rollno", rollnolists)); //rollnolists arraylist contains 250 strings studentcriteria.setprojection(projections.projectionlist().add(projections.property("studentid"))); list<long> studentids = new arraylist<long>(); list<long> results = (arraylist<long>) studentcriteria.list(); if (results != null && results.size() > 0) { studentids.addall(results); } return studentids;
what problem why so. if same query running through management studio result retrieved without spikes , result retrieved within 1 seconds. solution???
edit1: hibernate generated query is,
select this_.student_id y0_ student_table this_ this_.roll_no in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
edit2: execution plan after indexing roll_no
create index i_student_roll_no on student_table (roll_no)
,
the query run console cacheable , that's why response instantaneous. if @ query, you'll see parameters embedded in query, query planner can detect there's no variation , executions go same plan , same cached result.
the query run hibernate, if native query, uses preparedstatement
, parameters bind @ query execution time , to quote 1 of best author on indexing:
what has bind parameters?
the shared execution plan caches of db2, oracle , sql server use hash value of literal sql string key cache. cached plans not found if sql contains literal values vary each execution.
place holders (bind parameters) unify statement sql string identical when executed different values—thus, increasing cache-hit rate.
to solve it, need add index on both (roll_no
, student_id
) columns query becomes index-only scan.
sql server defaults cluster indexes, limit 1 clustered index per table, might want turn table heap table
instead , focus on index-only scans.