spring boot jpa mysql query performing slow - spring-boot

I have flow which fetches some data from the table using simple query(no joins). I triggered two requests one at t and other at t+10 minutes but both response came at same time for 1st request it took 20 mins for second request it took 10 mins. So I checked that query it is taking more time (about 20 mins) but same query I ran through mysql console taking 110 seconds. How can I improve the performance
Code to fetch data from db:
#Query(nativeQuery = true,
value = "select id, expiry_date as expiryDate "
+ "from checkout_extension "
+ "where expiry_date between :date and :nextDate",
countQuery = "select count(id) "
+ "from checkout_extension "
+ "where expiry_date between :date and :nextDate")
Page<CheckoutExpiryNotification> findByExpiryDateBetween(
final Date date, final Date nextDate, final Pageable pageable);
The same query taking very less time through mysql console. How can I improve performance?

Related

Limit user to post certain number of comments per article

Somehow I'm running in circles for two days! I have MySQL Database and comments table in witch I have id, user_id, date, published_at, body, likes and dislikes. How to limit user for max 10 comments per day. Of course I have user table.
I know I have somehow to count number of comments for certain date and put it in security context but I don't know how. I've tried with some native queries in
Repository like:
#Query(value = "select count from comments WHERE published_at=?1 AND user_id=?2", nativeQuery = true)
public int brojPostovaPoDanuPoUseru(Date datum, Integer user_id);
I guess I should find logged user name from SecurityContext and after that find his id, but then again what if there are two users with a same name, and where to use SecurityContext to find this.
At least some guidelines please :)
You can implement this on database level. My idea would be to save the time in seconds in date ( using Java: System.currentTimeMillis()). Then when you query by the user id, you can sort the results by date in descending order and filter for the top 10. Then you would pick the smallest number in date and check if it was less then 24h ago, if so you could then return an exception.
This would be an example query:
select * from (SELECT * FROM `comments` where comments.user_id=?1 ORDER BY `comments`.`date` DESC limit 10) as c order by c.date ASC limit 1
Let's say you saved date in secods using System.currentTimeMillis() / 1000. Now with the query result you would first calculate the seconds in hours and then in a day. This results in 86400 seconds. Now you would calculate the current time in seconds and extract it with the 24h in seconds as calculated before. And then you would check if this calculated result is smaller than the value of date this would indicate that the last 10th comment was made within the 24 hours.
This is the sample code in your repository:
#Query("select * from (SELECT * FROM `comments` where comments.user_id=?1 ORDER BY `comments`.`date` DESC limit 10) as c order by c.date ASC limit 1", nativeQuery=true)
public Comments getLastTenthComment(int userId);
This is the sample code in your service:
public boolean isAllowedToComment(int userId){
Comment comment = repository.getLastTenthComment(userId);
int dayInSeconds = 86400;
long currentTime = System.currentTimeMillis() / 1000;
long yesterdayInSeconds = currentTime - dayInSeconds;
if(comment.getDate() >= yesterdayInSeconds){
return false;
}
return true;
}

Hibernate + Postgres: simple query with bad performance

In my JavaEE webapplication, I am querying a postgres database to get the data of an employees holidays.
The table holiday has the following columns:
id bigint NOT NULL
start timestamp without time zone NOT NULL
end timestamp without time zone NOT NULL
employee_id bigint (FK referencing PK of table employee, indexed)
some other columns that do not seem to be related to my issue. Not much data in here.
Goal: Find any holiday entry of a specific employee concerning a given time interval (not necessarily completely, i.e. a holiday from 2009-12-30 to 2010-01-05 is a valid result when searching for holidays from 2010-01-01 to 2010-01-31).
That said, my named Query is:
SELECT
h
FROM
Holiday h
WHERE
h.employee.id = :employeeIdParam
AND (
h.end BETWEEN :fromParam AND :toParam
OR
h.start BETWEEN :fromParam AND :toParam
)
Query execution using hibernate takes ~400ms, resulting in 100 selected rows out of only 2000 rows in total. Much too long, isn't it?
(Using pgAdmin, it takes ~12ms.)
What's the issue here?
(Running on local machine - it's not a connection problem)
Using Wildfly 9.0, Postgres 9.4, Hibernate 4.3.1.
Update
Database Log:
select holiday0_.id as id1_70_, holiday0_.end as end3_70_, holiday0_.employee_id as emplo10_70_, holiday0_.start as star6_70_
from holiday holiday0_ where holiday0_.employee_id=$1 and (holiday0_.end between $2 and $3 or holiday0_.start between $4 and $5)",
"Parameter: $1 = '2757', $2 = '2003-07-01 00:00:00', $3 = '2015-08-11 23:59:59', $4 = '2003-07-01 00:00:00', $5 = '2015-08-11 23:59:59'"

query by day in PL/SQL(oracle)

I am querying from database:
select * from database where id = 12345
and i get a couple of days where it is equal to
3/4/2010 9:16:59 AM
but if i add
and date = to_date('03/04/2010','DD/MM/YYYY')
giving me
select * from database where id = 12345
and date = to_date('03/04/2010','DD/MM/YYYY')
I comeback with completely nothing.
Any pointers?
btw, I know that there is a time on there, but I don't know how to compare just based on the day!!!
That's because when you are creating the date, you implicitly set the time to 0:00:00, and as 0:00:00 is not equal to 9:16:59, you'll not get the date returned.
To tell Oracle to ignore the time part, just do the following:
WHERE id = 12345
AND trunc(date) = to_date('03/04/2010', 'DD/MM/YYYY')
WHERE id = 12345
AND date >= TO_DATE('03/04/2010', 'DD/MM/YYYY')
AND date < TO_DATE('03/04/2010', 'DD/MM/YYYY') + INTERVAL '1' DAY
http://use-the-index-luke.com/sql/where-clause/obfuscation/dates

HQL query to filter date from datetime data

I want to convert datetime format to string format in HQL count.
For example, I have redundant attendance data in each day of month of multiple employee which I need to count and get distinct data for a single day.
select Count(distinct att.AttDate) from AttendanceTable att where att.AttDate between '" + startDate.Date + "' and '" + endDate.Date + "'
but this query counting each and every datetime data because of time value. So I need to convert datetime into string.
HQL allows only certain set of functions.
Try
select count(distinct (
day(att.AttDate) +
31 * month(att.AttDate) +
366 * year(att.AttDate) ))
You could try str() or cast() but the result won't be consistent over different databases.

How to get one record before start date and end date

I want to get one record before start date and end date
DtpFrom means – 'date picker from
DtpTo means – 'date picker to
VB 6 CODE
sdate = DateToString(dtpFrom)
edate = DateToString(dtpTo)
QUERY
Where DATE BETWEEN '" & sdate & "' AND '" & edate & "'"
I want to get one record before sdate and edate
I tried this code
VB 6 CODE
s1sdate = -sdate
e1edate= -edate
QUERY
Where DATE BETWEEN '" & s1date & "' AND '" & e1date & "'"
But it is going one day minus
Example
Selecting 03/05/2009 to 03/06/2009 from date picker, but it showing record from
02/05/2009 to 02/06/2009.
I want to display one record before from the selecting date and ending date, not one day before, because my table is not a continous date.
ADDITIONAL EXAMPLE:
If we have a table and rows [ ID(int) , Value(Money) ] and we have some rows in it
ID --Value
1------70
2------100
3------150
8------200
20-----250
45-----280
and we want to make Query that get each row ID, Value and the previous Row Value in which data appear as follow
ID --- Value ---Prev_Value
1 ----- 70 ---------- 0
2 ----- 100 -------- 70
3 ----- 150 -------- 100
8 ----- 200 -------- 150
20 ---- 250 -------- 200
45 ---- 280 -------- 250
i make the following query but i think it's so bad in performance in huge amount of data
select t1.id, t1.value, t2.value from table t1 inner join table t2 on t1.id = t2.id where t2.value = (select max(value) from table t where t.value< t1.value and t.id = t1.id ) and T1.value BETWEEN '" & sdate & "' AND '" & edate & "'
Need VB 6 CODE OR ACCESS QUERY HELP.
SELECT * FROM whatever
WHERE DATE < sdate
ORDER BY DATE DESC
LIMIT 1
I don't think end date really matters if you want "the one before the records between start and end date"
But if you want the record right before start date AND the record right before end date you could just repeat the above query with edate instead of sdate.
This is what the query actually means: Select every record with a DATE before this one (sdate). For all of those records, order them by DATE in a descending manner (DESC). Only return the first one (LIMIT 1).
Note: Some implementations vary. You may need to use TOP 1 after the word SELECT instead of LIMIT 1

Resources