Simple SQL query taking a long time - mysql

I have a query that I use to determine what the interval is between timestamps of gauge data using the 2 most recent readings:
$interval_query = sprintf("SELECT `stamp`
FROM `processed_gauge_data`
WHERE `processed_gauge_data`.`gauge_id` IN (%s)
ORDER BY `processed_gauge_data`.`stamp` DESC LIMIT 2;",
$gauge_id
);
Here is an image with EXPLAIN results as well as the structure of the table:
http://i.imgur.com/QJmHmeb.png?1
This has worked fine for most gauges, but there are 2 in particular that it takes 30-45 seconds to execute this query. Selecting all data for those 2 gauges takes less than a second. What is causing this? I don't understand what's going on.

Turns out it was because of ORDER BY processed_gauge_data.stamp DESC. I changed my query to ORDER BY 'id' and it went from 30-45 seconds to .0006-.0003 seconds:
$interval_query = sprintf("SELECT `stamp`, 'id'
FROM `processed_gauge_data`
WHERE `processed_gauge_data`.`gauge_id` IN (%s)
ORDER BY `processed_gauge_data`.`id` DESC LIMIT 2;",
$gauge_id
);

Related

How can i make order by faster?

When i use ORDER BY in large table (160000 rows) like this:
select HomeTeam,AwayTeam,FTR,FTHG,FTAG,HS,`AS`,`Date`,Elo1A,Elo1B,Elo2A,Elo2B,Elo3A,Elo3B,Elo4A,Elo4B,nElo1A,nElo1B,nElo2A,
nElo2B,nElo3A,nElo3B,nElo4A,nElo4B from historic
where (HomeTeam='Crystal Palace' or AwayTeam='Crystal Palace') and datediff('1994-08-20',Date)>0 order by `Date` desc limit 1
fetch duration is 1.078 sec / 0.000 sec
When i use without ORDER BY like this:
select HomeTeam,AwayTeam,FTR,FTHG,FTAG,HS,`AS`,`Date`,Elo1A,Elo1B,Elo2A,Elo2B,Elo3A,Elo3B,Elo4A,Elo4B,nElo1A,nElo1B,nElo2A,
nElo2B,nElo3A,nElo3B,nElo4A,nElo4B from historic
where (HomeTeam='Crystal Palace' or AwayTeam='Crystal Palace') and datediff('1994-08-20',Date)>0 limit 1
fetch duration is 0.187 sec / 0.000 sec
Problem is that without ORDER BY i get wrong result:
Crystal Palace Tranmere 1993-08-14
but correct is with ORDER BY like this:
Crystal Palace Watford 1994-05-08
How can i avoid ORDER BY or somehow smarter call last match from current match?
As per our conversation in comments you have created index on date field and getting performance by it-
Further you can try below query which may provide you better performance-
SELECT HomeTeam,AwayTeam,FTR,FTHG,FTAG,HS,`AS`,`Date`,Elo1A,Elo1B,Elo2A,Elo2B,Elo3A,Elo3B,Elo4A,Elo4B,nElo1A,nElo1B,nElo2A,
nElo2B,nElo3A,nElo3B,nElo4A,nElo4B FROM historic
WHERE (HomeTeam='Crystal Palace' OR AwayTeam='Crystal Palace') and `Date` < '1994-08-20' ORDER BY `Date` DESC LIMIT 1;
Note: Here I just remove function from date field so that it can use index to filter data also.

MySql; how do you find time between two queries and sort them by least time

I have the following question to answer:
For each tag, retrieve the 10 to-dos with quickest completion time (i.e. the time between the creation and the completion of the to-do)
I tried this
Select *
From ToDoItem, Tag, ItemTag
Where
time between CreationDate and
CompletionDate is ASC AND
Tag.Id = ItemTag.ToDoId AND
ItemTag.TagId = ToDoItem.Id
Limit 10
So I first want to find the time between the creation date and completion date and after that I want them asc so it sorts them om time getting more, after that I select all the tags and at last I want to limit them to max 10.
But this doesn't work and I think the problem in somewhere in the "Time between creationdate and CompletionDate".
So the question I have is the following:
How do you find the time between two different tables with dates in it?
Description of table
2 issues with your query:
You need to use datediff() function to get the time between.
Ordering the results ahould be done with order by statement, not in the where part.
Select *
From ToDoItem, Tag, ItemTag
Where
Tag.Id = ItemTag.ToDoId AND
ItemTag.TagId = ToDoItem.Id
Order by datediff(completiontime, creationtime) asc
Limit 10

mysql compare 3 columns order on overall

I have a game that a user can save there name and score in a database.
Columns
Name, Tries, Percentage correct, Time taken, Image set
3 of these columns are based on a score
Tries, Percentage correct, Time taken,
Currently I have the table display time ascending.
$sql = "SELECT * FROM Score ORDER BY time ASC LIMIT 5";
Is there away to compare the scores
This is an example of 2 scores
1st row: 46, 52%, 02:36
2nd row: 38, 63%, 02:47
Is there away that i can compare on average which of those should be top based on all 3 scores.
Row one had more tries and less percentage correct but faster time.
Row two had less tries and higher percentage correct but slower time.
In a theory tries: ASC, percent: DESC, time Asc
If I change the Order by to:
$sql = "SELECT * FROM Score ORDER BY 'time ASC', 'tries ASC', 'percent
DESC' LIMIT 5";
Will it mess the rows up or will it display them in an order based on all 3
This image is using time ASC
The minimum amount of tries is 12 which will be 100%
Some how I need to compare Tries with Time
Can I divide time / tries and then order by result
Is the right?
$sql = "SELECT * FROM Score ORDER BY time / tries ASC LIMIT 5";
If you want to divide 2 columns then order that result use
$sql = "SELECT * FROM Score ORDER BY time / tries ASC LIMIT 18446744073709551615";
Then if you wish you can display that result in your table
For example
<td>".round($data[4] / $data[2],2)." Seconds</td>
/ will divide time by tries and then wrap with round() to round down the result.
In this case I would recommend round(??? ,2) which will output something like 3.53 Seconds
If you want an average score then use time + tries - percent
Lowset possible tries = 12
Time could be still high even with 12 tries
getting 12 tries will give 100% that is a high value so its best to minus that.
12 tries + 1m 30s - 100%
12 tries + 10h 30m 30s - 100%
This is too long for a comment.
"Is there away that i can compare on average which of those should be top based on all 3 scores?"
Yes. But first you have to figure out what the method is. Then you can implement it in a query.
Second, your query as written is:
SELECT *
FROM Score
ORDER BY 'time ASC', 'tries ASC', 'percent DESC'
LIMIT 5;
This will do nothing, because it is ordering by three constants. Drop the single quotes, and only use them for string constants:
SELECT *
FROM Score
ORDER BY time ASC, tries ASC, percent DESC
LIMIT 5;
In practice, this would be very much like:
ORDER BY time ASC
unless a lot of people have exactly the same time on two rows, the additional ordering criteria will not be used.

limit after group of the result mysql

I have following the mysql query
SELECT * FROM tbltest WHERE DATE(posted_date) BETWEEN '20120414' AND '20130414' GROUP BY title ORDER BY mostviewed DESC LIMIT 30
Problem:
It return only 19 rows where row of duplicate title is eliminated but I want to return 30 rows after grouping. How can I do this?
LIMIT 30 - limits the result to a maximum of 30, but if you have less results according tot he filter you are using you get as much results as your query finds as long as less than 30.
If you wish more than 30 results you will need to change your filter, but only to get more results is non usual reason for changing a filter.

Getting the last database entry with sql is very slow

My database has two columns : time and work. Its very very large and still growing.
I want to select the last entry:
$sql = "SELECT time, work FROM device ORDER BY time DESC LIMIT 1"
It takes 1.5 seconds to response it. How can I speed this up?. Because I repeat it 20 times.
I can't wait 20 seconds.
Greetings!
use MAX
SELECT *
FROM tableName
WHERE time = (SELECT MAX(time) FROM device)
add also an Index on column time
I was wondering why do you want to repeat this 20 times. If you are working on the application lebel, maybe you can add the result in a variable so you won't execute it again.