我遇到了一个优化问题,我无法弄清楚为什么我的查询太慢了。
这是我的实体:
@Entity
@Table(name = "CLIENT")
public class Client {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CLIENT_ID")
@SequenceGenerator(name = "ID_GENERATOR", sequenceName = "CLIENT_S", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_GENERATOR")
private Long id;
@Column(name="LOGIN")
private String login;
@Column(name="PASSWORD")
private String password;
和DAO
@NoRepositoryBean
public interface ClientDao extends JpaRepository<Client, Long>, JpaSpecificationExecutor<Client> {
Client findByPasswordAndLogin(@Param("login") String customerLogin,@Param("password") String customerHashedPassword);
}
当执行方法findByPasswordAndLogin时,完成大约需要200ms(通过Junit测试和JProfiler都可以看到)。
这里是Hibernate查询: Hibernate:选择clientx0_.CLIENT_ID作为CLIENT_ID1_4_,clientx0_.LOGIN作为LOGIN9_4_,clientx0_.PASSWORD作为PASSWORD10_4_,clientx0_.STATUT作为STATUT13_4_来自CLIENT clientx0_,其中clientx0_.PASSWORD =?和clientx0_.LOGIN =?
当我在数据库上手动执行SQL查询时,只需3ms:
select * from CLIENT where PASSWORD='xxxxx' and LOGIN='yyyyyyyy'
我们的开发环境中有4000个客户。超过一百万的生产。
这里是上下文:
有什么想法吗?
答案 0 :(得分:2)
我测试了不同类型的DAO(我不在这里发布代码,因为它太脏了):
注意:
我可以使用:
但是:
所以:
带有 RowMapper 的 Spring JDBCTemplate 似乎是提高特定案例性能的最佳解决方案。 我们可以保持SQL查询的安全性。 但是需要编写特定的RowMapper来将ResultSet转换为Entity。
Spring JDBCTemplate示例
@Repository
public class ClientJdbcTemplateDao {
private final Logger logger = LoggerFactory.getLogger(ClientJdbcTemplateDao.class);
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public List<Client> find() {
List<Client> c = this.jdbcTemplate.query( "SELECT login FROM Client WHERE LOGIN='xxxx' AND PASSWORD='xxx'", new ClientRowMapper());
return c;
}
}
Client RowMapper的示例
public class ClientRowMapper implements RowMapper<Client> {
@Override
public Client mapRow(ResultSet arg0, int arg1) throws SQLException {
// HERE IMPLEMENTS THE CONVERTER
// Sample :
// String login = arg0.getString("LOGIN")
// Client client = new Client(login);
// return client;
}
}
也许可以更好,任何建议都是受欢迎的。