Home » Performance » MySQL » ORDER BY ..LIMIT using indexes still slow
| ORDER BY ..LIMIT using indexes still slow [message #2890] |
Fri, 04 April 2008 10:53  |
gorzo Messages: 2 Registered: April 2008 |
Junior Member |
|
|
Hello,
I have a typical 3 table inner join with an ORDER BY and LIMIT clause that runs great for smaller data sets, but when the order by column has >800,000 rows it is take 2 minutes to complete. The EXPLAIN is showing Using temporary; Using filesort in the first table and I cannot seem to get rid of it. Any help would be great appracited.
SQL statement:
select distinct cm.message_datetime, c.keyword, cm.message_status, cm.num_recipients, cm.message_title
from users_community_role ucr, community c, company_message cm
where ucr.users_id=461
and ucr.community_id=c.community_id
and c.community_id=cm.community_id
order by cm.company_message_id
desc limit 5;
/////////////////
Here is the explain:
////////////////
mysql> explain select distinct cm.message_datetime, c.keyword, cm.message_status, cm.num_recipients, cm.message_title from users_community_role ucr, community c, company_message cm where ucr.users_id=461 and ucr.community_id=c.community_id and c.community_id=cm.community_id order by cm.company_message_id desc limit 5\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ucr
type: ref
possible_keys: FK_users_community_role_1,FK_users_community_role_2,users_in d
key: users_ind
key_len: 8
ref: const
rows: 98
Extra: Using where; Using index; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
type: eq_ref
possible_keys: PRIMARY,community_id
key: community_id
key_len: 8
ref: ucr.community_id
rows: 1
Extra:
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: cm
type: ref
possible_keys: comm_cm_index,company_message_community_id_fkey,comm_cmmsgdt
key: comm_cm_index
key_len: 9
ref: c.community_id
rows: 59
Extra: Using where
3 rows in set (0.00 sec)
/////////////////
Here are the indexes:
////////////////////
mysql> show index from users_community_role\G;
*************************** 1. row ***************************
Table: users_community_role
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: users_community_role_id
Collation: A
Cardinality: 4204
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 2. row ***************************
Table: users_community_role
Non_unique: 1
Key_name: FK_users_community_role_1
Seq_in_index: 1
Column_name: users_id
Collation: A
Cardinality: 89
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 3. row ***************************
Table: users_community_role
Non_unique: 1
Key_name: FK_users_community_role_2
Seq_in_index: 1
Column_name: community_id
Collation: A
Cardinality: 2102
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 4. row ***************************
Table: users_community_role
Non_unique: 1
Key_name: users_ind
Seq_in_index: 1
Column_name: users_id
Collation: A
Cardinality: 89
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 5. row ***************************
Table: users_community_role
Non_unique: 1
Key_name: users_ind
Seq_in_index: 2
Column_name: community_id
Collation: A
Cardinality: 4204
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 1. row ***************************
Table: community
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: community_id
Collation: A
Cardinality: 986
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 2. row ***************************
Table: community
Non_unique: 0
Key_name: community_id
Seq_in_index: 1
Column_name: community_id
Collation: A
Cardinality: 986
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 3. row ***************************
Table: community
Non_unique: 1
Key_name: community_company_id_fkey
Seq_in_index: 1
Column_name: company_id
Collation: A
Cardinality: 58
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 4. row ***************************
Table: community
Non_unique: 1
Key_name: FK_community_2
Seq_in_index: 1
Column_name: default_users_id
Collation: A
Cardinality: 1
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 1. row ***************************
Table: company_message
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: company_message_id
Collation: A
Cardinality: 854352
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 2. row ***************************
Table: company_message
Non_unique: 0
Key_name: company_message_id
Seq_in_index: 1
Column_name: company_message_id
Collation: A
Cardinality: 854352
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 3. row ***************************
Table: company_message
Non_unique: 0
Key_name: comm_cm_index
Seq_in_index: 1
Column_name: community_id
Collation: A
Cardinality: 14480
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 4. row ***************************
Table: company_message
Non_unique: 0
Key_name: comm_cm_index
Seq_in_index: 2
Column_name: company_message_id
Collation: A
Cardinality: 854352
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 5. row ***************************
Table: company_message
Non_unique: 1
Key_name: company_message_mobile_offer_id_fkey
Seq_in_index: 1
Column_name: mobile_offer_id
Collation: A
Cardinality: 17
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 6. row ***************************
Table: company_message
Non_unique: 1
Key_name: company_message_community_id_fkey
Seq_in_index: 1
Column_name: community_id
Collation: A
Cardinality: 17
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 7. row ***************************
Table: company_message
Non_unique: 1
Key_name: company_message_user_request_id_fkey
Seq_in_index: 1
Column_name: user_request_id
Collation: A
Cardinality: 17
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 8. row ***************************
Table: company_message
Non_unique: 1
Key_name: comp_message_message_date_index
Seq_in_index: 1
Column_name: message_datetime
Collation: A
Cardinality: 34174
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
*************************** 9. row ***************************
Table: company_message
Non_unique: 1
Key_name: comm_cmmsgdt
Seq_in_index: 1
Column_name: community_id
Collation: A
Cardinality: 407
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
*************************** 10. row ***************************
Table: company_message
Non_unique: 1
Key_name: comm_cmmsgdt
Seq_in_index: 2
Column_name: message_datetime
Collation: A
Cardinality: 170870
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Thank you in advance and please let me know if I left out any critcal information.
Thanks,
Brian
[Updated on: Fri, 04 April 2008 11:11]
|
|
| |
| Re: ORDER BY ..LIMIT using indexes still slow [message #2895 is a reply to message #2891 ] |
Fri, 04 April 2008 13:20   |
gorzo Messages: 2 Registered: April 2008 |
Junior Member |
|
|
Thanks for your reply.
We need the DISTINCT because the users_community_role table is denormalized. We can have many users_id - community_id matching entries. We need this for some other optimizations but it is hurting us here and maybe we need to re-think that.
FYI...here are table structures.
CREATE TABLE `users_community_role` (
`users_community_role_id` bigint(20) unsigned NOT NULL auto_increment,
`community_id` bigint(20) unsigned NOT NULL default '0',
`users_id` bigint(20) unsigned NOT NULL default '0',
`uuid` varchar(36) NOT NULL default '',
`role_name` varchar(255) default NULL,
`group_name` varchar(255) default NULL,
`date_created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`date_updated` timestamp NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`users_community_role_id`),
KEY `FK_users_community_role_1` (`users_id`),
KEY `FK_users_community_role_2` (`community_id`),
CONSTRAINT `FK_users_community_role_1` FOREIGN KEY (`users_id`) REFERENCES `users` (`users_id`),
CONSTRAINT `FK_users_community_role_2` FOREIGN KEY (`community_id`) REFERENCES `community` (`community_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `community` (
`community_id` bigint(20) unsigned NOT NULL auto_increment,
`keyword` varchar(100) default NULL,
PRIMARY KEY (`community_id`),
UNIQUE KEY `community_id` (`community_id`),
KEY `FK_community_2` USING BTREE (`default_users_id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 10240 kB;
CREATE TABLE `company_message` (
`company_message_id` bigint(20) unsigned NOT NULL auto_increment,
`uuid` varchar(36) default NULL,
`status` tinyint(4) default '0',
`community_id` bigint(20) unsigned default NULL,
`message_title` varchar(250) default NULL,
`message_text` text NOT NULL,
`message_status` varchar(50) default NULL,
`message_datetime` timestamp NOT NULL default '0000-00-00 00:00:00',
`num_recipients` bigint(20) unsigned default NULL,
PRIMARY KEY (`company_message_id`),
UNIQUE KEY `company_message_id` (`company_message_id`),
KEY `company_message_community_id_fkey` (`community_id`),
CONSTRAINT `company_message_community_id_fkey` FOREIGN KEY (`community_id`) REFERENCES `community` (`community_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
|
| |
| Re: ORDER BY ..LIMIT using indexes still slow [message #2950 is a reply to message #2905 ] |
Mon, 14 April 2008 11:47   |
hairroot Messages: 7 Registered: April 2008 |
Junior Member |
|
|
hi, guys, I am glad to join this thread, since I've encountered with the same problem.
to safari:
I've also tested your suggested sql, instead of using a filesort, mysql now use index on the order by column, but....It's still SLOW.
select * from FileMirrors where md5 in(select md5 from MD5Keyword where keyword='mp3') order by mirrors desc limit 1000, 10
in the upper sql, subquery from MD5Keyword produces about 30,000 records, I guess this is the main reason that produces poor performance.
|
|
| | | |
| Re: ORDER BY ..LIMIT using indexes still slow [message #2955 is a reply to message #2954 ] |
Tue, 15 April 2008 04:45   |
hairroot Messages: 7 Registered: April 2008 |
Junior Member |
|
|
hi, safari, thanks for your reply
The table DDL:
CREATE TABLE `MD5Keyword_new` (
`md5` varchar(50) NOT NULL,
`keyword` varchar(50) DEFAULT NULL,
KEY `NewIndex1` (`md5`),
KEY `NewIndex2` (`keyword`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `FileMirrors` (
`md5` varchar(50) NOT NULL,
`mirrors` int(11) DEFAULT '0',
PRIMARY KEY (`md5`),
KEY `NewIndex1` (`mirrors`),
KEY `NewIndex2` (`md5`,`mirrors`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2 facts need to be mentioned:
1. there are 380,000 records in MD5Keyword_new
2. there are 30,000 records in FileMirrors
the problem is,
when I executing the following query, it takes 30+ seconds.
select t1.*, t2.mirrors from MD5Keyword_new t1, FileMirrors t2 where t1.keyword = 'andy' and t2.md5=t1.md5 order by t2.mirrors desc limit 0, 10
explain it returns:
1 SIMPLE t1 ref NewIndex1,NewIndex2 NewIndex2 153 const 3512 Using where; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY,NewIndex2 PRIMARY 152 MazeCommunity_Final.t1.md5 1
the FileMirrors.mirrors index seems not being used, so I tested another query:
select * from FileMirrors where md5 in (select md5 from MD5Keyword_new where keyword='andy') order by mirrors limit 0, 10
explain it returns:
1 PRIMARY FileMirrors index \N NewIndex1 5 \N 1010 Using where; Using index
2 DEPENDENT SUBQUERY MD5Keyword_new index_subquery NewIndex1,NewIndex2 NewIndex1 152 func 2 Using where
now the index on FileMirrors.mirrors is being used, but unfortunately this query cost even longer time to return.
Any suggestion will be great!
Thank you.
|
|
|
| Re: ORDER BY ..LIMIT using indexes still slow [message #2956 is a reply to message #2955 ] |
Tue, 15 April 2008 06:03   |
safari Messages: 26 Registered: August 2006 Location: Vietnam |
Junior Member |
|
|
got it.
the slowness comes from table MD5Keyword_new, please create an index on (keyword, md5) and use the query:
select * from FileMirrors where md5 in (select md5 from MD5Keyword_new where keyword='andy') order by mirrors limit 0, 10
[Updated on: Tue, 15 April 2008 06:07]
|
|
| | | | |
Goto Forum:
Current Time: Fri Jul 10 01:21:15 EDT 2009
Total time taken to generate the page: 0.04912 seconds |