For date and time indexing purposes, of the following, which is the best/best practice/fastest?
keep a type date and another for time and have index on type date column
keep a single datetime column and simply put an index on type datetime column
have two, a datetime column and a date column, but put a single index on date
keep a type date and another for time and have index on both , first date and then time
any other approach?
I want to query a table for detecting changes, so I need both date and time.
UPDATE : I thought datetime indexing would take much more space than a date, so it would effect systems performance, is it true?
Assuming you are trying to save the date and the time that is on the same day as the date:
A datetime column can be used by date queries as well as time based queries. I can't see a reason why you would want another field.
I'd suggest using a unix timestamp in a int field, easiest to add, subtract and compare. You can convert to different formats for display.
Related
I am trying to delete the record from the specific date range .
So I have used the below query
delete from `table_name` where `date`<1580947200
I have used datetime as data type for the date column
It takes long time to execute and sometimes it gets stuck while executing this query.
Can anyone say how to apply index for this query
Your issue is not indexing. Your issue is that your telling MySQL to numerically compare a non-numeric (DATETIME) column against a numeric value (Unix timestamp).
i have used datetime as datatype for date column
This means the column is a DATETIME column. But;
1580947200
looks to me like a Unix Timestamp value.
Unix Timestamp is not the same as a MySQL DateTime entity.
Therefore; you need to CAST these two types to the same for the comparison; To do this you can use the UNIX_TIMESTAMP() MySQL Function.
DELETE FROM `table_name` WHERE UNIX_TIMESTAMP(`date`) < 1580947200
If you do wish to add an index to the date column you can read this Q&A.
How is smart to use date as primary value instead ID?
Where I can get better search mysql database performace:
to use timestamp: 1394319600
or to format date and use it as: 09032014
09032014 = 1394319600 = 9.Mart 2014
You likely should not be using a datetime type of data field as a primary key to begin with. I would suggest using autoincrementing integer field to guarantee uniqueness.
Now with regards to the datetime/timestamp field itself it is almost always better to use a native datetime or timestamp data type for these columns rather than string representations such a unix timestamps or other formatted date strings.
Why? Because when people put in timestamp data into their database base, they typically get to the point of wanting to run queries against that data. If you store your data in a non-native datetime format, you will typically need to convert it to such a format before you can use it in typical date/time functions that would be used in this sort of query. This usually means you lose the ability to leverage any index on the field for the query.
For example, say you wanted to run a query to see all records for the current day. With unix timestamp field that query may look like:
SELECT * FROM table
WHERE FROM_UNIX_TIMESTAMP(timestamp_field)
BETWEEN CONCAT(CURRENT_DATE(), ' 00:00:00') AND CONCAT(CURRENT_DATE(), ' 23:59:59')
whereas with a datetime/timestamp filed it would look like:
SELECT * FROM table
WHERE timestamp_field
BETWEEN CONCAT(CURRENT_DATE(), ' 00:00:00') AND CONCAT(CURRENT_DATE(), ' 23:59:59')
Here the simple requirement to use FROM_UNIX_TIMESTAMP() on the left hand side of the WHERE condition in the first query prevents use of an index since FROM_UNIX_TIMESTAMP(timestamp_field) does not exist in memory like timestamp_field would if properly indexed. This means you now need to do a full table scan to execute that query. If you have a large table, this could be very problematic.
I am currently working on a Mailbox for a website, holding a large number of messages within a database, where there is an option to filter the mails according to the date. I am in a confusion as of which method to use and how to.
Method 1:
To use a TIMESTAMP column and select the records based on the DATE part only. This seems to be better considering that the TIMESTAMP is the datatype meant to do this. But when filtering, wouldn't the splitting (to date and time) and comparisons be more expensive. If better, how to perform the comparison? (Input : yyyy-mm-dd)
Method 2:
To use a column each for TIME and DATE. Then compare the date field value to the filter param (of the format : yyyy-mm-dd). This seems expensive at inserting a new record (mail), which happens only one at a time. But the filtering requires comparison of a large number of records. So, seems to be more straight forward.
Also in method two, I am having a problem setting the default value as the CURRENT_DATE and CURRENT_TIME!
This is the Table creation code:
CREATE TABLE mailbox (
Mid INT NOT NULL AUTO_INCREMENT,
FromId INT NOT NULL,
ToId INT NOT NULL,
Subject VARCHAR(256) DEFAULT 'No Subject',
Message VARCHAR(2048) DEFAULT 'Empty Mail',
SDate DATE DEFAULT CURRENT_DATE,
STime TIME DEFAULT CURRENT_TIME,
PRIMARY KEY (Mid),
);
Please help...
I would use method 1 and do the filtering with
WHERE
your_timestamp >= search_date
AND
your_timestamp < search_date + INTERVAL 1 DAY
assuming your search_date is of type DATE.
MySQL can use an index in this case.
See this fiddle.
Have a look at the execution plan to verify the use of the index.
I suggest first that you maintain the records in the table sorted by date. Doing so, allows you to not need to compare every value, but you can use binary search to find the two boundaries (begin and end) of records with the desired date.
I would also use the time stamp. If you store is as timesstamp and not as text, it will be number, and its very fast at doing the comparison.
Here's my table right now (using mysql):
SQL Table: koko_table
name varchar(140)
status varchar(140)
time TIMESTAMP
My issue basically is , I have a form (using php) which user uses to store data only in the status column, my time column captures the time as a permanent data when the user stores in the status column. I think I have not been using accurate DATATYPE for time column, because everytime I visit my database, the time column has different values.
What can be the correct datatype to store time of status input by the user as un-changeable data.
The best data type would be DATETIME.
You can use either TIMESTAMP or DATETIME in MySQL to store date and time.
There are differences though:
TIMESTAMP uses 4 bytes, DATETIME 8 bytes.
Timestamps can be between 1970 and 2038, while datetimes can be between 1000-01-01 00:00:00 and 9999-12-32 23:59:59.
TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the (server's) current time zone for retrieval. This does not happen for DATETIME values where no timezone is implied.
Datetime fields have to be declared in INSERT operations while timestamp fields have the special feature that the first timestamp of a table is (by default) automatically inserted or updated at every INSERT or UPDATE operation with the current timestamp. (That's probably what you are seeing in your scenario.) You can change this behaviour, so only Inserts or only Updates set the timestamp to current timestamp. See MySQL docs: Timestamp properties
To have for example the timestamp automatically stored at Inserts but not changed during Updates, you could set:
ALTER TABLE TableName
CHANGE TimeStampName TimeStampName TIMESTAMP DEFAULT CURRENT_TIMESTAMP ;
I'd prefered DATETIME (the long number) or store it as a formated string like 2011/10/18 13:50. The first one is better in performance and the secound one is easyer to edit on phpMyAdmin or something like that.
I have a field that's in datetime format when date would be better and more consistent with the rest of the database, so I want to convert. The time part is all 00:00:00 anyway.
How can I do this in MySQL?
Thanks.
If you want this in a SELECT-Statement, just use the DATE Operator:
SELECT DATE(`yourfield`) FROM `yourtable`;
If you want to change the table structurally, just change the datatype to DATE (of course only do this if this doesn't affect applications depending on this field).
ALTER TABLE `yourtable` CHANGE `yourfield` `yourfield` DATE;
Both will eliminate the time part.
Cast it as a DATE:
select DATE(my_date_time)
That will truncate the time from it, leaving only the date part.
when using change we have to repeat the same name again for the field.now we can use MODIFY to alter the filed type.
ALTER TABLE `yourtable` MODIFY `yourfield` DATE;