Updating TimeStamp field a Slow Query in MySQL - mysql

My Table structure
CREATE TABLE IF NOT EXISTS `login` (
`eMail` varchar(50) NOT NULL,
`Password` tinytext NOT NULL,
`UID` int(9) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(16) NOT NULL,
`Text` tinytext NOT NULL,
`OldText` tinytext NOT NULL,
`LastSeen` timestamp NULL DEFAULT NULL,
`SecurityQuestion` tinytext NOT NULL,
`SecurityAnswer` tinytext NOT NULL,
PRIMARY KEY (`UID`),
UNIQUE KEY `eMail` (`eMail`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
When ever i try to update the LastSeen it shows as slow query [get logged into the slow query log file]
Can someone tell me whats wrong ?
A Sample SQL code [PHP]
$time = date("Y-m-d H:i:s");
UPDATE LOGIN set LastSeen=? WHERE UID=?
mysqli_stmt_bind_param($stmt,"si",$time,$uid);
Edit:
I need the Timestamp cause i want to subtract current time with the data from the row. By default Timestam is automatically updated on each update, but it can be changed though [in my table the LastSeen filed is not automatically updated].

You shouldn't be updating a timestamp column: timestamp columns are automatically updated to the current time whenever you update the row.
If you want an updatable "timestamp" column in mysql, use the datetime datatype.

Related

Create trigger and stored procedure that updates Datetime when user is authenticated

I created a Login System in PHP and MySQL and I have the following table for the users:
CREATE TABLE `users` (
`ID` int(11) NOT NULL,
`Authenticated` tinyint(1) NOT NULL DEFAULT 0,
`Name` varchar(20) NOT NULL,
`Surname` varchar(20) NOT NULL,
`Username` varchar(20) NOT NULL,
`Email` varchar(255) NOT NULL,
`Password` varchar(70) NOT NULL,
`Created_At` datetime DEFAULT current_timestamp(),
`Authenticated_At` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
When the user signs up, a user is inserted in the table users with Authenticated = 0. I, as the admin, have to authenticate the user using:
UPDATE users SET Authenticated = 1 WHERE ID = {$id};
What I'd like to know is how to create a trigger and a stored procedure that updates the Authenticated_At column to the current Date and Time after the aforementioned UPDATE query.
Thanks in advance.
1) The simplest possible solution :
UPDATE users SET Authenticated = 1, Authenticated_At = NOW() WHERE ID = {$id};
2) Another solution is to set a DEFAULT value for the timestamp value. This is implemented in the table definition, like :
CREATE TABLE `users` (
`ID` int(11) NOT NULL,
`Authenticated` tinyint(1) NOT NULL DEFAULT 0,
`Name` varchar(20) NOT NULL,
`Surname` varchar(20) NOT NULL,
`Username` varchar(20) NOT NULL,
`Email` varchar(255) NOT NULL,
`Password` varchar(70) NOT NULL,
`Created_At` datetime DEFAULT current_timestamp(),
`Authenticated_At` datetime DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
From the documentation :
An auto-updated column is automatically updated to the current timestamp when the value of any other column in the row is changed from its current value. An auto-updated column remains unchanged if all other columns are set to their current values. To prevent an auto-updated column from updating when other columns change, explicitly set it to its current value. To update an auto-updated column even when other columns do not change, explicitly set it to the value it should have (for example, set it to CURRENT_TIMESTAMP).
In order for the Authenticated_At timestamp to be automatically updated every time the record is updated (while not updating Created_At), you want :
UPDATE users SET Authenticated = 1, Created_At = Created_At WHERE ID = {$id};
3) As wisely commented by #Raymond Nijland, the best solution is to define the timestamp column to be autoupdated only on UPDATE operations, like :
`Authenticated_At` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Mysql Partition that will delete data that is 30 days older

Mysql table structure is as follows :
CREATE TABLE `golden` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`query` varchar(255) NOT NULL DEFAULT '',
`store` varchar(255) NOT NULL,
`augment` longtext NOT NULL,
`intent` longtext NOT NULL,
`parsed_query` longtext NOT NULL,
`query_store` longtext NOT NULL,
`FSN` longtext,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `myIndex` (`query`,`updated_at`)
) ENGINE=InnoDB AUTO_INCREMENT=1837 DEFAULT CHARSET=utf8;
This table gets populated with 5000 queries everyday. Need a way to partition the data on 'updated_at' so that it will have only 60 days data and older data will get auto deleted.
Fairly new to this whole mysql partitions. Please help!

MYSQL check difference between dates and update table acordingly

I want to apply update to a table row through mysql prepared statement based on time difference between column installed and actual time DATEDIFF.
Here is my update and insert statement:
CREATE TABLE `installs` (
`idinstalls` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(45) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`DateTime` varchar(255) DEFAULT NULL,
`channelpref` varchar(255) DEFAULT NULL,
`contractorid` varchar(45) DEFAULT NULL,
`additiona` varchar(255) DEFAULT NULL,
`mail` varchar(255) DEFAULT NULL,
`installed` varchar(255) DEFAULT NULL,
`version` varchar(45) DEFAULT NULL,
`process` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idinstalls`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=latin1;
INSERT INTO `installs` VALUES (1,'1478997547716','Test instalation 1','2016-12-05 10:47:21',NULL,NULL,'Test',NULL,'2016-11-13 01:39:07',NULL,''),(2,'1478997633546','Tomo','2017-01-24 16:05:10',NULL,NULL,'Test',NULL,'2016-11-13 01:40:33',NULL,''),(3,'1479003293243','Test instalation 2','2017-01-24 04:26:49',NULL,NULL,'Test',NULL,'2016-11-13 03:14:53',NULL,''),(4,'1479118582052','Beta','2016-11-21 19:40:10',NULL,NULL,'Test','','2016-11-14 11:16:22',NULL,''),(5,'1479124220728','Beta 2','2017-01-22 15:54:41',NULL,NULL,'Test','','2016-11-14 12:50:20',NULL,''),(14,'1480154887591','','2016-11-26 12:41:01',NULL,NULL,NULL,NULL,'2016-11-26 11:08:07',NULL,''),(17,'1483456759196','','2017-01-13 11:42:06',NULL,NULL,NULL,NULL,'2017-01-03 16:19:20',NULL,''),(18,'1484474379679','','2017-01-24 12:12:41',NULL,NULL,NULL,NULL,'2017-01-15 10:59:41',NULL,'')
The columns that are relevant to this question are: key,name,installed and process.
Query should update column process based on these requisites:
If column name has a input (it is not null nor empty field) column process should be assigned value '1'.
If column name does not have input, query should check difference between 2 dates, first one is date and time that is in column installed for that row and other is actual current date and time, if datetime difference is greater than 30 days it should update column process for that row to a value '0'.
This is my Fiddle
You should use the datatype timestamp for columns DateTime and installed. Then you may do the following.
update installs set process = '1' where name is not null and name != '';
update installs set process = '0' where (name is null or name = '') and datediff(now(), installed) > 30;
If I was asking the question, I'd formulate the data set this way, and construct my question accordingly...
CREATE TABLE `installs` (
`idinstalls` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(45) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`installed` varchar(255) DEFAULT NULL,
PRIMARY KEY (`idinstalls`)
);
INSERT INTO `installs` VALUES
( 1,'16','Test instalation 1','2016-11-13 01:39:07'),
( 2,'46','Tomo' ,'2016-11-13 01:40:33'),
( 3,'43','Test instalation 2','2016-11-13 03:14:53'),
( 4,'52','Beta' ,'2016-11-14 11:16:22'),
( 5,'28','Beta 2' ,'2016-11-14 12:50:20'),
(14,'91','' ,'2016-11-26 11:08:07'),
(17,'96','' ,'2017-01-03 16:19:20'),
(18,'79','' ,'2017-01-15 10:59:41');

Which column(s) to index in MySQL

I'm trying to optimize the following table, according to phpMyAdmin several stats regarding Table Scans are high and indices do not exist or are not being used. (Handler read rnd next 5.7 M)
1.
$query = "
SELECT * FROM apps_discrep
WHERE discrep_station = '$station'
AND discrep_date = '$date'
ORDER BY discrep_timestart";
2.
$query = "
SELECT * FROM apps_discrep
WHERE discrep_date BETWEEN '$keyword' AND '$keyword3'
AND (discrep_station like '$keyword2%') ORDER BY discrep_date";
Would it be correct to Index discrep_station, discrep_date, and discrep_timestart?
There currently only exist the Primary Unique Index on the auto-increment ID.
-- Table structure
`index` int(11) NOT NULL AUTO_INCREMENT,
discrep_station varchar(5) NOT NULL,
discrep_timestart time NOT NULL,
discrep_timestop time NOT NULL,
discrep_date date NOT NULL,
discrep_datetime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
discrep_show varchar(31) NOT NULL,
discrep_text text NOT NULL,
discrep_by varchar(11) NOT NULL,
discrep_opr varchar(11) NOT NULL,
email_traffic varchar(3) NOT NULL,
email_techs varchar(3) NOT NULL,
email_promos varchar(3) NOT NULL,
email_spots varchar(3) NOT NULL,
eas_row varchar(11) NOT NULL,
PRIMARY KEY (`index`)
ENGINE=MyISAM DEFAULT CHARSET=utf8;
It looks to me like you can get both queries with the same BTREE index, since that allows you to use the left-most tuples as a separate index.
Consider this MySQL doc page as a reference.
ALTER TABLE xxx ADD KEY `key1` (`discrep_station`, `discrep_date`, `discrep_timestart`) USING BTREE;
Your first query will use all 3 fields in the index. The second query will only use the first 2 fields in the index.

MYSQL: Find and delete similar records - Updated with example

I'm trying to dedup a table, where I know there are 'close' (but not exact) rows that need to be removed.
I have a single table, with 22 fields, and uniqueness can be established through comparing 5 of those fields. Of the remaining 17 fields, (including the unique key), there are 3 fields that cause each row to be unique, meaning the dedup proper method will not work.
I was looking at the multi table delete method outlined here: http://blog.krisgielen.be/archives/111 but I can't make sense of the final line of code (AND M1.cd*100+M1.track > M2.cd*100+M2.track) as I am unsure what the cd*100 part achieves...
Can anyone assist me with this? I suspect I could do better exporting the whole thing to python, doing something with it, then re-importing it, but then (1)I'm stuck with knowing how to dedup the string anyway! and (2) I had to break the record into chunks to be able to import it into mysql as it was timing out after 300 seconds so it turned into a whole debarkle to get into mysql in the first place.... (I am very novice at both mysql and python)
The table is a dump of some 40 log files from some testing. The test set for each log is some 20,000 files. The repeating values are either the test conditions, the file name/parameters or the results of the tests.
CREATE SHOW TABLE:
CREATE TABLE `t1` (
`DROID_V` int(1) DEFAULT NULL,
`Sig_V` varchar(7) DEFAULT NULL,
`SPEED` varchar(4) DEFAULT NULL,
`ID` varchar(7) DEFAULT NULL,
`PARENT_ID` varchar(10) DEFAULT NULL,
`URI` varchar(10) DEFAULT NULL,
`FILE_PATH` varchar(68) DEFAULT NULL,
`NAME` varchar(17) DEFAULT NULL,
`METHOD` varchar(10) DEFAULT NULL,
`STATUS` varchar(14) DEFAULT NULL,
`SIZE` int(10) DEFAULT NULL,
`TYPE` varchar(10) DEFAULT NULL,
`EXT` varchar(4) DEFAULT NULL,
`LAST_MODIFIED` varchar(10) DEFAULT NULL,
`EXTENSION_MISMATCH` varchar(32) DEFAULT NULL,
`MD5_HASH` varchar(10) DEFAULT NULL,
`FORMAT_COUNT` varchar(10) DEFAULT NULL,
`PUID` varchar(15) DEFAULT NULL,
`MIME_TYPE` varchar(24) DEFAULT NULL,
`FORMAT_NAME` varchar(10) DEFAULT NULL,
`FORMAT_VERSION` varchar(10) DEFAULT NULL,
`INDEX` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`INDEX`)
) ENGINE=MyISAM AUTO_INCREMENT=960831 DEFAULT CHARSET=utf8
The only unique field is the PriKey, 'index'.
Unique records can be established by looking at DROID_V,Sig_V,SPEED.NAME and PUID
Of the ¬900,000 rows, I have about 10,000 dups that are either a single duplicate of a record, or have upto 6 repetitions of the record.
Row examples: As Is
5;"v37";"slow";"10266";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/7";"image/tiff";"Tagged Ima";"3";"191977"
5;"v37";"slow";"10268";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/8";"image/tiff";"Tagged Ima";"4";"191978"
5;"v37";"slow";"10269";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/9";"image/tiff";"Tagged Ima";"5";"191979"
5;"v37";"slow";"10270";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/10";"image/tiff";"Tagged Ima";"6";"191980"
5;"v37";"slow";"12766";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/7";"image/tiff";"Tagged Ima";"3";"193977"
5;"v37";"slow";"12768";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/8";"image/tiff";"Tagged Ima";"4";"193978"
5;"v37";"slow";"12769";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/9";"image/tiff";"Tagged Ima";"5";"193979"
5;"v37";"slow";"12770";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/10";"image/tiff";"Tagged Ima";"6";"193980"
Row Example: As It should be
5;"v37";"slow";"10266";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/7";"image/tiff";"Tagged Ima";"3";"191977"
5;"v37";"slow";"10268";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/8";"image/tiff";"Tagged Ima";"4";"191978"
5;"v37";"slow";"10269";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/9";"image/tiff";"Tagged Ima";"5";"191979"
5;"v37";"slow";"10270";;"file:";"V1-FL425817.tif";"V1-FL425817.tif";"BINARY_SIG";"MultipleIdenti";"20603284";"FILE";"tif";"2008-11-03";;;;"fmt/10";"image/tiff";"Tagged Ima";"6";"191980"
Please note, you can see from the index column at the end that I have cut out some other rows - I have only idenitified a very small set of repeating rows. Please let me know if you need any more 'noise' from the rest of the DB
Thanks.
I figured out a fix - using the count function, I was using a COUNT(*) that just returned everything in the table, by using a COUNT (distinct NAME) function I am able to weed out the dup rows that fit the dup critera (as set out by the field selection in a WHERE clause)
Example:
SELECT `PUID`,`DROID_V`,`SIG_V`,`SPEED`, COUNT(distinct NAME) as Hit FROM sourcelist, main_small WHERE sourcelist.SourcePUID = 'MyVariableHere' AND main_small.NAME = sourcelist.SourceFileName
GROUP BY `PUID`,`DROID_V`,`SIG_V`,`SPEED` ORDER BY `DROID_V` ASC, `SIG_V` ASC, `SPEED`;