I want to create a table so that I have an ID number that is based on the date, AND an ID as a unique, primary key.
Ie:
2015-2-1-1
2015-2-1-2
but, if I create:
2015-2-2-1
the counter should restart at 1.
I've tried using the following:
CREATE TABLE `invoices` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
`po_id` int(11) unsigned DEFAULT NULL,
`description` varchar(256) NOT NULL,
`client_id` int(11) unsigned DEFAULT NULL,
`status` enum('unpaid','paid','partial') DEFAULT 'unpaid',
PRIMARY KEY (`id`,`date`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;
But it doesn't work like I want.
If you want a two column primary key (date, id) and id that should auto increment starting from 1 each date. Just set date, for your primary column key, and id in second position in your key definition.
CREATE TABLE `invoices` (
`date` date NOT NULL,
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`po_id` int(11) unsigned DEFAULT NULL,
`description` varchar(256) NOT NULL,
`client_id` int(11) unsigned DEFAULT NULL,
`status` enum('unpaid','paid','partial') DEFAULT 'unpaid',
PRIMARY KEY (`date`, `id`)
) ENGINE=MyIsam DEFAULT CHARSET=latin1;
The internal key will be set as your example, but you will see two columns:
+----+------------+
| id | date |
+----+------------+
| 1 | 2012-01-01 |
| 2 | 2012-01-01 |
| 1 | 2012-01-02 |
| 2 | 2012-01-02 |
+----+------------+
EDIT: You have to use MyIsam format
Related
I am still new to SQL and I am trying to improve the performance of my query. I have been searching around and have come to the conclusion that using JOINS instead of so many WHERE INS would help improve my performance, but I am unsure of how I would convert my statement. This is my current statement.
SELECT stop_id, stop_name FROM stops WHERE stop_id IN (
SELECT DISTINCT stop_id FROM stop_times WHERE trip_id IN (
SELECT trip_id from trips WHERE route_id = <routeid> ));
It takes anywhere from 5-25 seconds to return the results which is unacceptable. I was hoping to get it below 1 second. If anyone was wondering the data is from a GTFS feed. The stops and trips tables have about ~10,000 rows each, while the stop_times table has ~900,000. I have created indexes at each of the columns I am using. Here is the output of EXPLAIN, and also what was used to create each table.
Thanks for any help and if you need any more info let me know!
+----+--------------------+------------+-----------------+------------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+-----------------+------------------+---------+---------+------+------+-------------+
| 1 | PRIMARY | stops | ALL | NULL | NULL | NULL | NULL | 6481 | Using where |
| 2 | DEPENDENT SUBQUERY | stop_times | index_subquery | stop_id | stop_id | 63 | func | 63 | Using where |
| 3 | DEPENDENT SUBQUERY | trips | unique_subquery | PRIMARY,route_id | PRIMARY | 62 | func | 1 | Using where |
+----+--------------------+------------+-----------------+------------------+---------+---------+------+------+-------------+
| stops | CREATE TABLE `stops` (
`stop_id` varchar(20) NOT NULL,
`stop_code` varchar(50) DEFAULT NULL,
`stop_name` varchar(255) DEFAULT NULL,
`stop_desc` varchar(255) DEFAULT NULL,
`stop_lat` decimal(8,6) DEFAULT NULL,
`stop_lon` decimal(8,6) DEFAULT NULL,
`zone_id` int(11) DEFAULT NULL,
`stop_url` varchar(255) DEFAULT NULL,
`location_type` int(2) DEFAULT NULL,
`parent_station` int(11) DEFAULT NULL,
`wheelchair_boarding` int(2) DEFAULT NULL,
PRIMARY KEY (`stop_id`),
KEY `zone_id` (`zone_id`),
KEY `stop_lat` (`stop_lat`),
KEY `stop_lon` (`stop_lon`),
KEY `location_type` (`location_type`),
KEY `parent_station` (`parent_station`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
| stop_times | CREATE TABLE `stop_times` (
`trip_id` varchar(20) DEFAULT NULL,
`arrival_time` varchar(8) DEFAULT NULL,
`arrival_time_seconds` int(11) DEFAULT NULL,
`departure_time` varchar(8) DEFAULT NULL,
`departure_time_seconds` int(11) DEFAULT NULL,
`stop_id` varchar(20) DEFAULT NULL,
`stop_sequence` int(11) DEFAULT NULL,
`stop_headsign` varchar(50) DEFAULT NULL,
`pickup_type` int(2) DEFAULT NULL,
`drop_off_type` int(2) DEFAULT NULL,
`shape_dist_traveled` varchar(50) DEFAULT NULL,
KEY `trip_id` (`trip_id`),
KEY `arrival_time_seconds` (`arrival_time_seconds`),
KEY `departure_time_seconds` (`departure_time_seconds`),
KEY `stop_id` (`stop_id`),
KEY `stop_sequence` (`stop_sequence`),
KEY `pickup_type` (`pickup_type`),
KEY `drop_off_type` (`drop_off_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
| trips | CREATE TABLE `trips` (
`route_id` varchar(20) DEFAULT NULL,
`service_id` varchar(20) DEFAULT NULL,
`trip_id` varchar(20) NOT NULL,
`trip_headsign` varchar(255) DEFAULT NULL,
`trip_short_name` varchar(255) DEFAULT NULL,
`direction_id` tinyint(1) DEFAULT NULL,
`block_id` int(11) DEFAULT NULL,
`shape_id` varchar(50) DEFAULT NULL,
PRIMARY KEY (`trip_id`),
KEY `route_id` (`route_id`),
KEY `service_id` (`service_id`),
KEY `direction_id` (`direction_id`),
KEY `block_id` (`block_id`),
KEY `shape_id` (`shape_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
You're right in thinking that JOINS are usually faster than WHERE IN subqueries.
Try this:
SELECT T3.stop_id, T3.stop_name
FROM trips AS T1
JOIN
stop_times AS T2
ON T1.trip_id=T2.trip_id AND route_id = <routeid>
JOIN stops AS T3
ON T2.stop_id=T3.stop_id
GROUP BY T3.stop_id, T3.stop_name
The below query is taking around 10mins to 1 hr to execute. And due to this we are getting load spikes frequently. Can anyone please help rewrite the query in a more optimised way.
Query:
select count(*)
from t_tab6 tab1
left join t_tab6_element_tab2 tab2
on tab2.tab6_id = tab1.id
left join t_tab3 tab3
on tab1.create_tab3_id = tab3.id
left join t_tab4 tab4
on tab2.element_id = tab4.id and tab2.element_type_id = 1
left join t_tab7 tab5
on tab2.element_id = tab5.id and tab2.element_type_id = 2
where tab1.domain_id = 522
Explain plan:
+----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
| 1 | SIMPLE | tab1 | ref | domain_id_tab6_type_cd | domain_id_tab6_type_cd | 4 | const | 243430 | |
| 1 | SIMPLE | tab2 | ref | FK_tab6 | FK_tab6 | 4 | comp1.tab1.id | 2 | |
| 1 | SIMPLE | tab3 | eq_ref | PRIMARY | PRIMARY | 4 | comp1.tab1.create_tab3_id | 1 | Using index |
| 1 | SIMPLE | tab4 | ref | id | id | 4 | comp1.tab2.element_id | 1 | Using index |
| 1 | SIMPLE | tab5 | ref | id | id | 4 | comp1.tab2.element_id | 1 | Using index |
+----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
5 rows in set (0.45 sec)
Tables structure:
mysql> show create table t_tab6_element_tab2\G
*************************** 1. row ***************************
Table: t_tab6_element_tab2
Create Table: CREATE TABLE `t_tab6_element_tab2` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`element_type_id` int(11) NOT NULL,
`tab6_id` int(11) NOT NULL,
`element_id` int(11) NOT NULL,
`element_desc` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_tab6` (`tab6_id`),
KEY `element_type_id_element_id` (`element_type_id`,`element_id`)
) ENGINE=InnoDB AUTO_INCREMENT=45901159 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t_tab3\G
*************************** 1. row ***************************
Table: t_tab3
Create Table: CREATE TABLE `t_tab3` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`is_admin` int(11) DEFAULT NULL,
`phone` varchar(50) DEFAULT NULL,
`company` varchar(255) DEFAULT NULL,
`last_login` datetime DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`validate_code` varchar(50) DEFAULT NULL,
`has_login` smallint(6) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1304 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t_tab6\G
*************************** 1. row ***************************
Table: t_tab6
Create Table: CREATE TABLE `t_tab6` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`create_tab3_id` int(11) DEFAULT NULL,
`tab6_create_date` date DEFAULT NULL,
`tab6_type_cd` int(11) NOT NULL,
`tab6_desc` varchar(512) NOT NULL,
`IsGlobaltab6` int(2) DEFAULT NULL,
`tab6_start_date` datetime NOT NULL,
`tab6_end_date` datetime NOT NULL,
`job_id` int(11) DEFAULT NULL,
`domain_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `tab6_tab3_FK` (`create_tab3_id`),
KEY `domain_id_tab6_type_cd` (`domain_id`,`tab6_type_cd`)
) ENGINE=InnoDB AUTO_INCREMENT=8586007 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t_tab4\G
*************************** 1. row ***************************
Table: t_tab4
Create Table: CREATE TABLE `t_tab4` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tab4_name` varchar(255) DEFAULT NULL,
`tab4_value` varchar(255) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`description` varchar(2000) DEFAULT NULL,
`own_domain_id` int(11) DEFAULT NULL,
`rank_check` int(11) DEFAULT NULL,
`rank1` int(11) DEFAULT NULL,
`rank2` int(11) DEFAULT NULL,
`rank3` int(11) DEFAULT NULL,
`yesterday_entrances` int(11) DEFAULT NULL,
`week_entrances` int(11) DEFAULT NULL,
`current_ctr` float(16,4) DEFAULT NULL,
`monthly_search_volume` int(11) DEFAULT NULL,
`avg_monthly_search_volume` int(11) DEFAULT NULL,
`traffic_increase` int(11) DEFAULT NULL,
`rank_improvement` int(11) DEFAULT NULL,
`rank_update_date` date DEFAULT NULL,
`top_rank_tab5_id` int(11) DEFAULT NULL,
`frequency` int(10) DEFAULT '1',
`score` float DEFAULT NULL,
`create_date` datetime DEFAULT NULL,
`bing_rank1` int(10) DEFAULT NULL,
`bing_rank2` int(10) DEFAULT NULL,
`yesterday_bing_entrances` int(11) DEFAULT NULL,
`bing_rank_improvement` int(11) DEFAULT NULL,
KEY `id` (`id`),
KEY `tab4_name` (`tab4_name`),
KEY `own_domain_id` (`own_domain_id`,`rank_check`),
KEY `rank_check` (`rank_check`)
) ENGINE=InnoDB AUTO_INCREMENT=670267018 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`rank_check`)
(PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB,
PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)
mysql> show create table t_tab7\G
*************************** 1. row ***************************
Table: t_tab7
Create Table: CREATE TABLE `t_tab7` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`own_domain_id` int(11) DEFAULT NULL,
`url` varchar(2000) NOT NULL,
`create_date` datetime DEFAULT NULL,
`friendly_name` varchar(255) DEFAULT NULL,
`section_name_id` int(11) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`status` int(11) DEFAULT NULL,
`week_entrances` int(11) DEFAULT NULL,
`week_bounces` int(11) DEFAULT NULL,
`canonical_url_id` int(11) DEFAULT NULL,
KEY `id` (`id`),
KEY `urlindex` (`url`(255)),
KEY `own_domain_id_type_status` (`own_domain_id`,`type`,`status`),
KEY `canonical_url_id` (`canonical_url_id`),
KEY `type` (`type`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=237034388 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`type`)
(PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB,
PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.01 sec)
Try below
select count(*)
from (Select id,create_tab3_id from tab6 where domain_id = 522) as tab1
left join tab6_element_tab2 tab2
on tab2.tab1nt_id = tab1.id
left join t_tab3 tab3
on tab1.create_tab3_id = tab3.id
left join t_tab4 tab4
on tab2.element_id = tab4.id and tab2.element_type_id = 1
left join t_tab7 tab5
on tab2.element_id = tab5.id and tab2.element_type_id = 2
Remove left join t_tab3 tab3 if you are using for count only and if possible add domain type check in where clause
Define an index on the column used in your condition:
create index t_tab6_domain_id_index on t_tab6(domain_id);
The query itself seems fine.
1.query is taking around 10mins to 1 hr to execute.
2.due to this we are getting load spikes frequently.
3.please help me to rewrite the query.
4.also help me to improve the performance of query.
Query with explain plan
explain select count(*)
from t_event eve
left join t_event_element_rel rel on rel.event_id = eve.id
left join t_object object on eve.create_object_id = object.id
left join t_keyword keyword on rel.element_id = keyword.id and rel.element_type_id = 1
left join t_target_url targeturl on rel.element_id = targeturl.id and rel.element_type_id = 2
where eve.domain_id = 522
+----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
| 1 | SIMPLE | eve | ref | domain_id_event_type_cd | domain_id_event_type_cd | 4 | const | 243430 | |
| 1 | SIMPLE | rel | ref | FK_event | FK_event | 4 | company.eve.id | 2 | |
| 1 | SIMPLE | user | eq_ref | PRIMARY | PRIMARY | 4 | company.eve.create_user_id | 1 | Using index |
| 1 | SIMPLE | keyword | ref | id | id | 4 | company.rel.element_id | 1 | Using index |
| 1 | SIMPLE | targeturl | ref | id | id | 4 | company.rel.element_id | 1 | Using index |
+----+-------------+-----------+--------+-------------------------+-------------------------+---------+----------------------------+--------+-------------+
5 rows in set (0.45 sec)
Table structure:
mysql> show create table t_event_element_rel\G
*************************** 1. row ***************************
Table: t_event_element_rel
Create Table: CREATE TABLE `t_event_element_rel` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`element_type_id` int(11) NOT NULL,
`event_id` int(11) NOT NULL,
`element_id` int(11) NOT NULL,
`element_desc` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_event` (`event_id`),
KEY `element_type_id_element_id` (`element_type_id`,`element_id`)
) ENGINE=InnoDB AUTO_INCREMENT=45901159 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t_object\G
*************************** 1. row ***************************
Table: t_object
Create Table: CREATE TABLE `t_object` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`is_admin` int(11) DEFAULT NULL,
`phone` varchar(50) DEFAULT NULL,
`company` varchar(255) DEFAULT NULL,
`last_login` datetime DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`validate_code` varchar(50) DEFAULT NULL,
`has_login` smallint(6) DEFAULT NULL COMMENT 'if null or 0 then hasn''t login, first time login',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1304 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t_event\G
*************************** 1. row ***************************
Table: t_event
Create Table: CREATE TABLE `t_event` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`create_user_id` int(11) DEFAULT NULL,
`event_create_date` date DEFAULT NULL,
`event_type_cd` int(11) NOT NULL,
`event_desc` varchar(512) NOT NULL,
`IsGlobalEvent` int(2) DEFAULT NULL,
`event_start_date` datetime NOT NULL,
`event_end_date` datetime NOT NULL,
`job_id` int(11) DEFAULT NULL,
`domain_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `event_user_FK` (`create_user_id`),
KEY `domain_id_event_type_cd` (`domain_id`,`event_type_cd`)
) ENGINE=InnoDB AUTO_INCREMENT=8586007 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table t_keyword\G
*************************** 1. row ***************************
Table: t_keyword
Create Table: CREATE TABLE `t_keyword` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`keyword_name` varchar(255) DEFAULT NULL,
`keyword_value` varchar(255) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`description` varchar(2000) DEFAULT NULL,
`own_domain_id` int(11) DEFAULT NULL,
`rank_check` int(11) DEFAULT NULL,
`rank1` int(11) DEFAULT NULL COMMENT 'yesterday rank value',
`rank2` int(11) DEFAULT NULL COMMENT 'the day before yesterday rank value',
`rank3` int(11) DEFAULT NULL COMMENT 'special date rank for overstock.com',
`yesterday_entrances` int(11) DEFAULT NULL COMMENT 'yesterday entrances',
`week_entrances` int(11) DEFAULT NULL COMMENT '7 days entrances',
`current_ctr` float(16,4) DEFAULT NULL COMMENT 'Current CTR',
`monthly_search_volume` int(11) DEFAULT NULL COMMENT 'Most Recent Month search volume',
`avg_monthly_search_volume` int(11) DEFAULT NULL COMMENT 'avg_monthly_search_volume',
`traffic_increase` int(11) DEFAULT NULL COMMENT 'Traffic Increase',
`rank_improvement` int(11) DEFAULT NULL COMMENT 'Rank Improvement',
`rank_update_date` date DEFAULT NULL COMMENT 'rank be updated for Special Date',
`top_rank_targeturl_id` int(11) DEFAULT NULL,
`frequency` int(10) DEFAULT '1' COMMENT '1: daily, 2: weekly, 3: monthly',
`score` float DEFAULT NULL,
`create_date` datetime DEFAULT NULL,
`bing_rank1` int(10) DEFAULT NULL,
`bing_rank2` int(10) DEFAULT NULL,
`yesterday_bing_entrances` int(11) DEFAULT NULL,
`bing_rank_improvement` int(11) DEFAULT NULL,
KEY `id` (`id`),
KEY `keyword_name` (`keyword_name`),
KEY `own_domain_id` (`own_domain_id`,`rank_check`),
KEY `rank_check` (`rank_check`)
) ENGINE=InnoDB AUTO_INCREMENT=670267018 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`rank_check`)
(PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB,
PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)
mysql> show create table t_target_url\G
*************************** 1. row ***************************
Table: t_target_url
Create Table: CREATE TABLE `t_target_url` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`own_domain_id` int(11) DEFAULT NULL,
`url` varchar(2000) NOT NULL,
`create_date` datetime DEFAULT NULL,
`friendly_name` varchar(255) DEFAULT NULL,
`section_name_id` int(11) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`status` int(11) DEFAULT NULL,
`week_entrances` int(11) DEFAULT NULL COMMENT 'last 7 days entrances',
`week_bounces` int(11) DEFAULT NULL COMMENT 'last 7 days bounce',
`canonical_url_id` int(11) DEFAULT NULL COMMENT 'the primary URL ID, NOT allow canonical of canonical',
KEY `id` (`id`),
KEY `urlindex` (`url`(255)),
KEY `own_domain_id_type_status` (`own_domain_id`,`type`,`status`),
KEY `canonical_url_id` (`canonical_url_id`),
KEY `type` (`type`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=237034388 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`type`)
(PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB,
PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.01 sec)
The first line of your EXPLAIN shows a lot of rows for domain_id_event_type_cd, which is a compound index, yet in your query you only search on a part of the index (eve.domain_id = xxx). So unless domain 522 really has 243K entries, you can cut down on this by adding an index solely for domain_id.
Also, it seems you are trying to do an OR search by using rel.element_type_id as a "switch" for referencing different types of data. Since you are only interested in the count, I suggest you split the query in two parts, then add the results. This will cut down on the LEFT JOINS. You can even add the results within MySQL:
SELECT (SELECT COUNT (*) FROM ....) + (SELECT COUNT (*) FROM ...)
(You do know you can abuse SELECT to do math, don't you?)
any help would be appreciated.
I have 2 tables:
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`username_canonical` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`email_canonical` varchar(255) NOT NULL,
`enabled` tinyint(1) NOT NULL,
`salt` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`last_login` datetime DEFAULT NULL,
`locked` tinyint(1) NOT NULL,
`expired` tinyint(1) NOT NULL,
`expires_at` datetime DEFAULT NULL,
`confirmation_token` varchar(255) DEFAULT NULL,
`password_requested_at` datetime DEFAULT NULL,
`roles` longtext NOT NULL COMMENT '(DC2Type:array)',
`credentials_expired` tinyint(1) NOT NULL,
`credentials_expire_at` datetime DEFAULT NULL,
`messages_unread_count` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_1483A5E992FC23A8` (`username_canonical`),
UNIQUE KEY `UNIQ_1483A5E9A0D96FBF` (`email_canonical`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
and
CREATE TABLE `blog_posts` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
`title` varchar(255) NOT NULL,
`content` longtext NOT NULL,
`tags` varchar(512) NOT NULL,
`timestamp_created` datetime NOT NULL,
`timestamp_updated` datetime NOT NULL,
`is_visible` tinyint(1) NOT NULL,
`is_deleted` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_78B2F93212469DE2` (`category_id`),
KEY `IDX_78B2F932A76ED395` (`user_id`),
CONSTRAINT `FK_78B2F932A76ED395` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
CONSTRAINT `FK_78B2F93212469DE2` FOREIGN KEY (`category_id`) REFERENCES `blog_categories` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
and I want to select all post limiting the output with posts authors, give me an advice - how could I force the query to use indexes:
select p.*, u.* from blog_posts p join users u on p.user_id = u.id limit 0,10;
Explain output:
+----+-------------+-------+------+----------------------+----------------------+---------+----------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------------+----------------------+---------+----------+------+-------------+
| 1 | SIMPLE | u | ALL | PRIMARY | NULL | NULL | NULL | 1 | |
| 1 | SIMPLE | p | ref | IDX_78B2F932A76ED395 | IDX_78B2F932A76ED395 | 9 | sky.u.id | 1 | Using where |
+----+-------------+-------+------+----------------------+----------------------+---------+----------+------+-------------+
Is there any way to use index when joining users table?
Mysql will use an index automatically if you setup a FK relationship between blogposts.userid and and users.id.
So create the FK relationship:
CONSTRAINT blogposts_userid FOREIGN KEY (user_id) REFERENCES users (id)
When I insert a new row the treeId column is always 1.
The treeId column is not included in the insert statement.
What could be causing it to not increment?
My table code is
CREATE TABLE `users` (
`uuid` varchar(36) NOT NULL,
`parentUuid` varchar(36) DEFAULT NULL,
`treePath` text,
`treeId` int(11) NOT NULL AUTO_INCREMENT,
`firstName` varchar(50) NOT NULL,
`lastName` varchar(50) NOT NULL,
`email` varchar(255) NOT NULL,
`salt` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
`state` enum('subscribed','registered','banned') NOT NULL,
`dobMonth` int(11) DEFAULT NULL,
`dobYear` int(11) DEFAULT NULL,
`dateSubscribed` datetime DEFAULT NULL,
`dateRegistered` datetime DEFAULT NULL,
`gender` enum('unspecified','male','female') NOT NULL DEFAULT 'unspecified',
`dd` float DEFAULT '0',
`mainRegion` int(11) DEFAULT NULL,
PRIMARY KEY (`uuid`,`treeId`),
KEY `parentid` (`parentUuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
if you want it to auto-increment don't specify the treeId field in your insert.
Found the answer (Documentation)
For MyISAM and BDB tables you can specify AUTO_INCREMENT on a
secondary column in a multiple-column index. In this case, the
generated value for the AUTO_INCREMENT column is calculated as
MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. This is
useful when you want to put data into ordered groups.
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Which returns:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
So because I had a joint key on uuid (which is always unique) and on treeId (which is the auto-increment) then it was creating a new increment group each time.