简体   繁体   中英

Hibernate custom dialect for DATE function to speed up queries

The db of my app has many record (2 Milions) and I've several queries that use WHERE conditions on date field using the DATE() function. Example:

SELECT * from table WHERE DATE(column1)>=DATE(:parameter1) and DATE(column1)<=DATE(:parameter2)

These queries take too much time: about 150/170ms. After a bit of profiling I seen that the problem is the DATE() function. Converting the query to:

SELECT * from table WHERE column1>=:parameter1 and column1<=:parameter2

where parameter1 is the date with 00:00:00 time and where parameter2 is date with 23:59:59 time, the query take only 1/2ms.

So I should translate all HQL queries in my app, but I wanted try to use a custom function in Hibernate dialect that make for me this work.

For example creating a DATE_START() function that put in the query the date with 00:00:00 time and DATE_END() function that put in the query the date with 23:59:59 time.

Have you some good suggestion to do this in a "best practice" way?


A sql solution is required because it's better also in the case of Spring services with @Query annotation where there is not a Java implementation:

@Query(value = "SELECT * from table WHERE DATE(column1)>=DATE(?1) and DATE(column1)<=DATE(?2)")
 public List<MyObject> findByDate(Date date1,Date date2);

In these cases I can't use a Java solution.

I'd say you to create a method with java code below and reuse any time you want define initial and final time for your queries:

    Calendar initialCalendar = GregorianCalendar.getInstance();
    initialCalendar.setTime(dataInicial);
    initialCalendar.set(Calendar.HOUR_OF_DAY, 0);
    initialCalendar.set(Calendar.MINUTE, 0);
    initialCalendar.set(Calendar.SECOND, 0);
    initialCalendar.set(Calendar.MILLISECOND, 0);

    Calendar finalCalendar = GregorianCalendar.getInstance();
    finalCalendar.setTime(dataFinal);
    finalCalendar.set(Calendar.HOUR_OF_DAY, 23);
    finalCalendar.set(Calendar.MINUTE, 59);
    finalCalendar.set(Calendar.SECOND, 59);
    finalCalendar.set(Calendar.MILLISECOND, 999);

    Timestamp inicialDate = new Timestamp(initialCalendar.getTimeInMillis());
    Timestamp finalDate = new Timestamp(finalCalendar.getTimeInMillis());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM