Fast multi select MySQL and PHP - php

I'm searching for a method to query 2.704 MySQL selects in a fast way.
At the moment this queries need 202.91903 seconds, what is too slow.
What is the best way to do so many queries?
Why I need this?
I have 26 tables with entries from 24.11.2016 until today. Every minute there is a new entry. (time 10:00am until 04:00am - next day).
Now I need to select the newest entry of each day, but the latest entry could be at 04:00:00 but it also can be earlier (ex. 03:00 pm) I never know when the last entry was.
So I have following select:
SELECT `column1`, `column2`, `column3`
FROM `table`
WHERE `timestamp`>='2016-11-24 10:00:00' AND `timestamp`< '2016-11-25 04:01:00'
ORDER BY `id` DESC LIMIT 1
This select I make for every day and for every table.
Does anyone have a solution to speed this up?

create an index on your table for column timestamp. When your table rows is growing big, index will be require for it to search for your record fast. without index, it will be like you are searching for row 1 to the row you are looking for in million of rows.
Sample
create index index_name on table_name (column_name)

If i get you right...
I think you could change yours to this
SELECT `column1`, `column2`, `column3`
FROM `table`
WHERE date_format(`timestamp`,'%d/%m/%Y')=date_format(curdate(),'%d/%m/%Y')
ORDER BY `timestamp` DESC LIMIT 1
I am using timestamp and curdate() to select only the today records, order them by timestamp descending, so earlier will be on top and limit the rows to 1 so you will have only the earliest.

Related

How to select mySQL records based only on month and year without full table scan

I need to select records based on the month and year, The month and the year will come from PHP
so I have the query like
SELECT id, created FROM table_name WHERE YEAR(created) = 2020 AND MONTH(created) = 05 LIMIT 500;
Here created is the datetime field, The problem with this query is, It is working fine if the table has less records but when table records are increasing the query is becoming very slow
I have more than 10,000 records in my table for 2020-05 and a total of 1 million records so it takes approx 11 seconds to execute this query, I suspect this is because the query is doing a full table scan
Help me with a solution to make this query execute faster?
You are using YEAR() and MONTH() function in where clause when using a function in where clause MySQL doesn't use the index of that column to executing your query.
You can change your query to below and make a try
SELECT id, created FROM table_name WHERE created between '2020-05-01 00:00:00' and '2020-05-31 23:59:59'
** Don't forget to add an index to your field.

MYSQL: Return column time value based on current time?

OK I have a database with a table containing four columns. Each column has many records all with times of day entered with the mySQL TIME data type.
How do I go about querying the database and returning the time value nearest to the current time of day please?
I have it set up so that I have a simple webform that takes a user input of which column the user wants. I want the TIME value nearest to the current time from the chosen column returned to the user.
COLUMN1 COLUMN2 COLUMN3 COLUMN4
11:00 11:40 11:25 11:35
12:05 12:25 12:35 12:25
etc
So if the user enters "3" into the webform and the current time is 12:10 I'd like the 12:35 value returned to them.
I have been Googling and I believe I need to use CURTIME(). I don't want an answer for how to take the user input and use it to query which column. I just need to know how to return a column's time value closest to the current time please! Thank you.
Try out:
SELECT *
FROM table_name
WHERE time > CURTIME()
ORDER BY time ASC
LIMIT 1
EDIT:
Maybe this is the way to go
SELECT * FROM table_name AS T
WHERE T.time = (SELECT MIN(T2.time) FROM table_name AS T2
WHERE T2.time > ?)
The '?' is a placeholder for your reference time (by PHP).
You could do:
SELECT column3, TIMEDIFF(column3, CURTIME()) AS difference
FROM timetbl
ORDER BY ABS(difference) ASC
LIMIT 1
If you would need only closest times that are in the future (like when a user needs to catch a train), difference would need to be greater than 0, so you'd add WHERE TIMEDIFF(column3, CURTIME()) > '00:00'
Try this. it selects the last entry of time:
SELECT col1 FROM table_name order by col1 desc limit 1;

Will specifying a SUBTIME interval in MYSQL prevent the query from unnecessarily going through the entire table?

Please tell me, if I specify an interval like such: subtime(now(), INTERVAL 1 day) inside a MySQL SELECT query while having a proper datetime column to use as reference - will this prevent from the query to look through the entire table (over 100,000 records in my case) each time it runs but rather look through records made only the past 24 hours? Is DESC order needed for the datetime table or such? Also, if I have SUM(column) in the query, will it also run only for the interval specified?
Edit: If I just would like to use the above mentioned SUM to sum a column where there only are integers of value "1" - would it be better to simply check how many rows the SELECT query returns with mysql_num_rows - is it more efficient in combination with the time interval setting?
Thank you!
It will in fact prevent MySQL to go through the whole table but not if you just subtime() in the SELECT-part. Instead you have to do something like this:
SELECT * FROM myTable
WHERE myDateCol BETWEEN DATE_SUB(now(), INTERVAL 1 day) AND now()
The query will now select only rows one day old. Add a B-TREE index on myDateCol to speed things up:
ALTER TABLE myTable ADD INDEX myIdx USING BTREE (myDateCol)
See MySQL doc on that topic

Php mysql get the nearest-latest record if a record is not exist (datetime based)

Trying to get my head around, If I select a record such as WHERE item_id='$item_id' AND date(datetime)='2012-06-25' and if that record does not exist so I want to get the nearest-latest record after that date. How can I achieve that in a query?
All I can think of the only way right now is if num_of_rows is 0 then I add 3 days period ahead to that day and search again and get the DESC datetime LIMIT 1 (in case there are multiple rows). But who knows I can do it with just a query.
The record could have multiple rows in one day. So if a particular date has no record, how to get the next nearest available data given the same $item_id?
SELECT *
FROM table
WHERE field <= '2012-06-25'
ORDER BY field DESC
LIMIT 1
I think this is what you are looking for:
SELECT *
FROM my_table
WHERE datetime BETWEEN '2012-06-25 00:00:00' AND
DATE_ADD('2012-06-25 00:00:00', INTERVAL 3 DAY)
ORDER BY datetime ASC
LIMIT 1;
also create index on field datetime for faster performance.
This will bring back the item closest to the date that you enter into the query. It won't however look for before or after, just find the closest date to what you enter in.
select
min(abs(DATEDIFF(date(datetime),'2012-06-25'))) as minDiff
,yourID
from table1
group by yourID
order by 1 asc;

how to show one record per day order by id?

I have this little script that shows one wisdom each day.
so I have three columns.
Id wisdom timestamp
1 wisdon 1 4/1/2012
2 wisdon 2 4/1/2012
3 wisdon 3 4/2/2012
and I want to fetch array of one wisdom for each day
I looked around your website, but unfortunately I didn't find something similar to what I want.
also I got this code
$sql = mysql_query("SELECT DISTINCT id FROM day_table group by timestamp");
but this also not working.
any ideas?
is it possible to make a counter of 24 hours update wisdom date?
please give me some help.
You can make another table that is called wisdom_of_day
The table would have the following columns, id, wisdom_id, date
Basically each day you can randomly select a wisdom from your wisdom table and insert it into the wisdom day table. You can also add a constraint to your date column so it is distinct. It is important that it is a date column and not a timestamp since you don't care about time.
Then you can retrieve the wisdom of the day by querying based on the date.
It's possible I read your question wrong and you just want to select one wisdom for each day, but you want to show multiple days and you want to get the data from your table.
If so, the reason your query is not working is because you are grouping by a timestamp which includes the date and time. You need to group it by date for it to group like you want.
Here is a query that will group by the day correctly. This will only work if you have a timestamp field and are not storing a unix timstamp on an int column.
select id, wisdom, date(timestamp) date_only from day_table group by date_only order by date_only asc;
Hmm, I noticed that your timestamp values are in some kind of date format, maybe as a string? If so the above query probably won't work.
First compute number of days since 1970
SELECT DATEDIFF(CURDATE(), '1970-01-01')
Then insert this number inside RAND, for example:
SELECT * FROM table ORDER BY RAND(15767) LIMIT 1;
Rand with number as argument is deterministic.
Full query:
SELECT * FROM table ORDER BY RAND((SELECT DATEDIFF(CURDATE(), '1970-01-01'))) LIMIT 1;

Categories