http://topic.csdn.net/u/20090520/16/a96a2e90-a935-4460-837e-e52b4557c519.html
这个帖子中我一直强调的大数据量和小数据量的问题其实是个误导!
并不是因为数据量,而是某个索引没有起作用,导致了全表扫描!应该是这样,我不是百分百确定!现在,删除了几个不必要的索引,把问题集中锁定在如下语句:
EXPLAIN SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 1;
+----+-------------+-------------+-------+---------------+---------+---------+-------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------------------------+---------+-------------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 7300143 | |
| 1 | SIMPLE | E_role_info | ref | infoID | infoID | 4 | news_data.E_info.infoID | 7 | Using where |
+----+-------------+-------------+-------+---------------+---------+---------+-------------------------+---------+-------------+
E_info.infoID是主键,而且上边E_info的type项已经是index了,但不清楚为什么rows项的数值还是那么大,7300143 这个数字也恰恰是E_info的行数!
mysql> SELECT SQL_NO_CACHE COUNT(*) FROM E_info;
+----------+
| COUNT(*) |
+----------+
| 7300143 |
+----------+
所用的存储引擎是MyISAM,索引文件E_info.MYI是100M大小,我怀疑是索引太大,内存撑不下,老得访问磁盘所致,故而将key_buffer_size增加到512,可依然很慢,查第一条记录要18秒。
mysql>SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 1;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
+----------+---------------------+--------+---------+
1 row in set (18.89 sec)再描述一下E_role_info表,
mysql> show columns from E_role_info;
+---------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------------------+------+-----+---------+-------+
| infoID | int(8) unsigned | NO | MUL | 0 | |
| roleID | mediumint(6) unsigned | NO | | 0 | |
| related | smallint(3) unsigned | NO | | 0 | |
+---------+-----------------------+------+-----+---------+-------+
我在该表中插入一条记录
INSERT INTO E_role_info(infoID, roleID, related) values(42880361, 25669, 1); 这时很快就列出了刚刚记录的结果:
mysql> SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 1;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
+----------+---------------------+--------+---------+
1 row in set (0.00 sec)但,如果列出两条的话,就会由于以前数据的拖累,而很慢:
SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 2;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
+----------+---------------------+--------+---------+
2 rows in set (17.78 sec)通过结果可以看出,两次列出的值中42880361比42570652要新!所以,我估计是由于某种原因E_info的主键没有用上,即便explain的type值显示的是index.
extra中没有using filesort说明应该不是ORDER BY的问题,很可能是JOIN阶段的问题:
`E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID
E_info.infoID是本表的主键,E_role_info.infoID也建立了索引!
这个帖子中我一直强调的大数据量和小数据量的问题其实是个误导!
并不是因为数据量,而是某个索引没有起作用,导致了全表扫描!应该是这样,我不是百分百确定!现在,删除了几个不必要的索引,把问题集中锁定在如下语句:
EXPLAIN SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 1;
+----+-------------+-------------+-------+---------------+---------+---------+-------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------------------------+---------+-------------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 7300143 | |
| 1 | SIMPLE | E_role_info | ref | infoID | infoID | 4 | news_data.E_info.infoID | 7 | Using where |
+----+-------------+-------------+-------+---------------+---------+---------+-------------------------+---------+-------------+
E_info.infoID是主键,而且上边E_info的type项已经是index了,但不清楚为什么rows项的数值还是那么大,7300143 这个数字也恰恰是E_info的行数!
mysql> SELECT SQL_NO_CACHE COUNT(*) FROM E_info;
+----------+
| COUNT(*) |
+----------+
| 7300143 |
+----------+
所用的存储引擎是MyISAM,索引文件E_info.MYI是100M大小,我怀疑是索引太大,内存撑不下,老得访问磁盘所致,故而将key_buffer_size增加到512,可依然很慢,查第一条记录要18秒。
mysql>SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 1;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
+----------+---------------------+--------+---------+
1 row in set (18.89 sec)再描述一下E_role_info表,
mysql> show columns from E_role_info;
+---------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------------------+------+-----+---------+-------+
| infoID | int(8) unsigned | NO | MUL | 0 | |
| roleID | mediumint(6) unsigned | NO | | 0 | |
| related | smallint(3) unsigned | NO | | 0 | |
+---------+-----------------------+------+-----+---------+-------+
我在该表中插入一条记录
INSERT INTO E_role_info(infoID, roleID, related) values(42880361, 25669, 1); 这时很快就列出了刚刚记录的结果:
mysql> SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 1;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
+----------+---------------------+--------+---------+
1 row in set (0.00 sec)但,如果列出两条的话,就会由于以前数据的拖累,而很慢:
SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 2;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
+----------+---------------------+--------+---------+
2 rows in set (17.78 sec)通过结果可以看出,两次列出的值中42880361比42570652要新!所以,我估计是由于某种原因E_info的主键没有用上,即便explain的type值显示的是index.
extra中没有using filesort说明应该不是ORDER BY的问题,很可能是JOIN阶段的问题:
`E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID
E_info.infoID是本表的主键,E_role_info.infoID也建立了索引!
解决方案 »
- jdbc 执行 on duplicate key update 时出错,非空字段需要个缺省值
- MySQL 5.0 如何统计正在执行的查询语句数量呢?
- linux下如何使用C程序执行SQL脚本
- 关于mysql proxy的问题
- mysql5.0安全性如何?据说root密码可以reset?!同步和复制功能如何,支不支持双机热备份及同步?谢谢!来者有分
- mysql安装问题求助
- mysql中请问单凭以下这幅关系图如何才能关联最多3个表就可以查询front_cor_employ中的所有字段值?
- 帮忙!文字不能正常显示?
- mysql如何允许远程连接
- 查A表中字段B的值000-000-00000.abc中第二个-和.中间数据的SQL语句怎么写
- WIN7 下mysql的启动
- 关于mysql select*走非聚集索引的疑惑
+----+-------------+-------------+-------+---------------+---------------+---------+-------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------------+---------+-------------------------+---------+-------------+
| 1 | SIMPLE | E_info | index | idx_e_info_id | idx_e_info_id | 4 | NULL | 7300143 | |
| 1 | SIMPLE | E_role_info | ref | infoID | infoID | 4 | news_data.E_info.infoID | 7 | Using where |
+----+-------------+-------------+-------+---------------+---------------+---------+-------------------------+---------+-------------+
2 rows in set (0.03 sec)mysql> SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` FORCE INDEX(idx_e_info_id) INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 2;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
+----------+---------------------+--------+---------+
2 rows in set (25.73 sec)
show table status like 'E_info'; show index from E_role_info;
show index from E_info;select count(*) from E_role_info where roleID = 25669 ;
*************************** 1. row ***************************
Name: E_role_info
Engine: MyISAM
Version: 10
Row_format: Fixed
Rows: 72997534
Avg_row_length: 10
Data_length: 729975340
Max_data_length: 2814749767106559
Index_length: 745362432
Data_free: 0
Auto_increment: NULL
Create_time: 2009-05-26 14:12:43
Update_time: 2009-05-26 17:21:00
Check_time: 2009-05-26 14:19:33
Collation: gb2312_chinese_ci
Checksum: NULL
Create_options:
Comment: ????????mysql> show table status like 'E_info'\G
*************************** 1. row ***************************
Name: E_info
Engine: MyISAM
Version: 10
Row_format: Dynamic
Rows: 7300143
Avg_row_length: 130
Data_length: 951029956
Max_data_length: 281474976710655
Index_length: 179054592
Data_free: 0
Auto_increment: NULL
Create_time: 2009-05-26 18:04:41
Update_time: 2009-05-26 18:08:11
Check_time: 2009-05-26 18:09:31
Collation: gb2312_chinese_ci
Checksum: NULL
Create_options:
Comment: ???????
mysql> show index from E_role_info\G
*************************** 1. row ***************************
Table: E_role_info
Non_unique: 1
Key_name: infoID
Seq_in_index: 1
Column_name: infoID
Collation: A
Cardinality: 10428219
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment: mysql> show index from E_info\G
*************************** 1. row ***************************
Table: E_info
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: infoID
Collation: A
Cardinality: 7300143
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
mysql> select count(*) from E_role_info where roleID = 25669 ;
+----------+
| count(*) |
+----------+
| 30 |
+----------+
1 row in set (30.05 sec)
+-------------+--------+---------+------------+----------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+----------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-------------+--------+---------+------------+----------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+----------+
| E_role_info | MyISAM | 10 | Fixed | 72997534 | 10 | 729975340 | 2814749767106559 | 745362432 | 0 | NULL | 2009-05-26 14:12:43 | 2009-05-26 17:21:00 | 2009-05-26 14:19:33 | gb2312_chinese_ci | NULL | | ???????? |
+-------------+--------+---------+------------+----------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+----------+
mysql> show table status like 'E_info';
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
| E_info | MyISAM | 10 | Dynamic | 7300143 | 130 | 951029956 | 281474976710655 | 104653824 | 0 | NULL | 2009-05-27 09:06:05 | 2009-05-27 09:09:36 | NULL | gb2312_chinese_ci | NULL | | ??????? |
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
mysql> show index from E_role_info;
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 1 | infoID | 1 | infoID | A | 10428219 | NULL | NULL | | BTREE | |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)
mysql> show index from E_info;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A | 7300143 | NULL | NULL | | BTREE | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+mysql> select count(*) from E_role_info where roleID = 25669 ;
+----------+
| count(*) |
+----------+
| 30 |
+----------+
1 row in set (30.05 sec)
你将LEFT JOIN修改为INNER JOIN是否可行
SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669
慢
EXPLAIN结果:
+----+-------------+-------------+------+---------------+--------+---------+-------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+--------+---------+-------------------------+---------+-------------+
| 1 | SIMPLE | E_info | ALL | PRIMARY | NULL | NULL | NULL | 7300143 | |
| 1 | SIMPLE | E_role_info | ref | infoID | infoID | 4 | news_data.E_info.infoID | 7 | Using where |
+----+-------------+-------------+------+---------------+--------+---------+-------------------------+---------+-------------+SELECT SQL_NO_CACHE E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID and E_role_info.roleID = 25669;
也不行:
explain结果:
+----+-------------+-------------+------+---------------+--------+---------+-------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+--------+---------+-------------------------+---------+-------------+
| 1 | SIMPLE | E_info | ALL | PRIMARY | NULL | NULL | NULL | 7300143 | |
| 1 | SIMPLE | E_role_info | ref | infoID | infoID | 4 | news_data.E_info.infoID | 7 | Using where |
+----+-------------+-------------+------+---------------+--------+---------+-------------------------+---------+-------------+
指的是这些吗?mysql> show table status like 'E_role_info';
+-------------+--------+---------+------------+----------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+----------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-------------+--------+---------+------------+----------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+----------+
| E_role_info | MyISAM | 10 | Fixed | 72997534 | 10 | 729975340 | 2814749767106559 | 745362432 | 0 | NULL | 2009-05-26 14:12:43 | 2009-05-26 17:21:00 | 2009-05-26 14:19:33 | gb2312_chinese_ci | NULL | | ???????? |
+-------------+--------+---------+------------+----------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+----------+
mysql> show table status like 'E_info';
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
| E_info | MyISAM | 10 | Dynamic | 7300143 | 130 | 951029956 | 281474976710655 | 104653824 | 0 | NULL | 2009-05-27 09:06:05 | 2009-05-27 09:09:36 | NULL | gb2312_chinese_ci | NULL | | ??????? |
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
mysql> show index from E_role_info;
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 1 | infoID | 1 | infoID | A | 10428219 | NULL | NULL | | BTREE | |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)
mysql> show index from E_info;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A | 7300143 | NULL | NULL | | BTREE | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
mysql> select count(*) from E_role_info where roleID = 25669 ;
+----------+
| count(*) |
+----------+
| 30 |
+----------+
1 row in set (30.05 sec)
analyze table E_role_info ; analyze table E_info
另外你的表结构是不是如下。 E_role_info
+----------+--------+---------+
| infoID | roleID | related |
+----------+--------+---------+
| 42245717 | 413382 | 1004 |
| 42245750 | 413382 | 1006 |
| 42245774 | 413382 | 1006 | E_info
+----------+---------------------------------------+---------------------+
| infoID | info_title | info_time |
+----------+---------------------------------------+---------------------+
| 42245717 | 南昌工商巧助企业护“英雄” | 2009-04-09 12:33:43 |
| 42245774 | 4月12日北京龙翔永恒台球俱乐部千元周赛 | 2009-04-09 11:36:36 |
+----------+---------------------------------------+---------------------+
+---------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| infoID | int(11) | NO | PRI | NULL | |
| roleID | int(11) | NO | MUL | NULL | |
| related | int(11) | NO | | NULL | |
+---------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> desc E_info;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| infoID | int(11) | NO | PRI | NULL | |
| info_title | varchar(100) | NO | | NULL | |
| info_time | datetime | NO | | NULL | |
+------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> show index from E_role_info;
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 0 | PRIMARY | 1 | infoID | A | 30 | NULL | NULL | | BTREE | |
| E_role_info | 1 | idx_E_role_info_roleID | 1 | roleID | A | 10 | NULL | NULL | | BTREE | |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)mysql> show index from E_info;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A | 30 | NULL | NULL | | BTREE | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)mysql> explain
-> select E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.r
elated
-> FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID -> WHERE E_role_info.roleID = 3
-> ORDER BY E_info.infoID DESC LIMIT 1;
+----+-------------+-------------+--------+--------------------------------+------------------------+---------+-------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+--------------------------------+------------------------+---------+-------------------------+------+----------------------------------------------+
| 1 | SIMPLE | E_role_info | ref | PRIMARY,idx_E_role_info_roleID | idx_E_role_info_roleID | 4 | const | 7 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | E_info | eq_ref | PRIMARY | PRIMARY | 4 | test.E_role_info.infoID | 1 | |
+----+-------------+-------------+--------+--------------------------------+------------------------+---------+-------------------------+------+----------------------------------------------+
2 rows in set (0.00 sec)mysql>
mysql> show index from E_role_info;
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 0 | PRIMARY | 1 | infoID | A | 30 | NULL | NULL | | BTREE | |
| E_role_info | 1 | idx_E_role_info_roleID | 1 | roleID | A | 10 | NULL | NULL | | BTREE | |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)E_role_info 这个表中的infoID不是主键,但有索引,infoID和roleID在该表中是多对多的关系!
数据类似+--------+--------+---------+
| infoID | roleID | related |
+--------+--------+---------+
| 2 | 1 | 20 |
| 2 | 3 | 20 |
| 2 | 4 | 20 |
| 3 | 2 | 30 |
| 3 | 5 | 30 |
| 4 | 1 | 40 |
| 4 | 2 | 40 |
| 4 | 4 | 40 |
| 4 | 5 | 40 |
| 5 | 5 | 50 |
是的,主键是(infoID,roleID)!不过我没有建立!
速度倒是提高了一倍,但是还是慢,并没解决主要问题:
explain:+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 7300143 | |
| 1 | SIMPLE | tmp_E_role_info1 | eq_ref | PRIMARY | PRIMARY | 7 | news_data.E_info.infoID,const | 1 | |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
+---------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| infoID | int(11) | NO | PRI | NULL | |
| roleID | int(11) | NO | PRI | NULL | |
| related | int(11) | NO | | NULL | |
+---------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> desc E_info;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| infoID | int(11) | NO | PRI | NULL | |
| info_title | varchar(100) | NO | | NULL | |
| info_time | datetime | NO | | NULL | |
+------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> show index from E_role_info;
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 0 | PRIMARY | 1 | infoID | A | 119 | NULL | NULL | | BTREE | |
| E_role_info | 0 | PRIMARY | 2 | roleID | A | 119 | NULL | NULL | | BTREE | |
| E_role_info | 1 | idx_E_role_info_roleID | 1 | roleID | A | 10 | NULL | NULL | | BTREE | |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.00 sec)mysql> show index from E_info;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A | 30 | NULL | NULL | | BTREE | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)mysql> select count(*) from E_role_info where roleID = 3 ;
+----------+
| count(*) |
+----------+
| 25 |
+----------+
1 row in set (0.00 sec)mysql> select E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 3
-> ORDER BY E_info.infoID DESC LIMIT 3;
+--------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+--------+---------------------+--------+---------+
| 30 | 2009-05-27 12:44:27 | 3 | 274 |
| 29 | 2009-05-27 12:43:52 | 3 | 225 |
| 28 | 2009-05-27 12:35:13 | 3 | 259 |
+--------+---------------------+--------+---------+
3 rows in set (0.00 sec)mysql> explain
-> select E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM `E_info` LEFT JOIN E_role_info ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 3
-> ORDER BY E_info.infoID DESC LIMIT 3;
+----+-------------+-------------+--------+--------------------------------+---------+---------+--------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+--------------------------------+---------+---------+--------------------------+------+-------------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 3 | |
| 1 | SIMPLE | E_role_info | eq_ref | PRIMARY,idx_E_role_info_roleID | PRIMARY | 8 | test.E_info.infoID,const | 1 | Using where |
+----+-------------+-------------+--------+--------------------------------+---------+---------+--------------------------+------+-------------+
2 rows in set (0.00 sec)mysql>
加上了,E_role_info(infoID,roleID)的主键,
速度倒是提高了一倍,但是还是慢,并没解决主要问题:
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 7300143 | |
| 1 | SIMPLE | tmp_E_role_info1 | eq_ref | PRIMARY | PRIMARY | 7 | news_data.E_info.infoID,const | 1 | |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------
E_info那一行的rows影响的行数还是那么大!
| infoID | roleID | related |
+----------+--------+---------+
| 30988323 | 25669 | 1002 |
| 31294141 | 25669 | 1050 |
| 31335712 | 25669 | 1049 |
| 31466752 | 25669 | 1002 |
| 31788492 | 25669 | 1017 |
| 31789503 | 25669 | 1011 |
| 31797856 | 25669 | 1003 |
| 31902436 | 25669 | 1006 |
| 31906371 | 25669 | 1013 |
| 32095002 | 25669 | 1003 |
| 32575477 | 25669 | 1002 |
| 32661765 | 25669 | 1002 |
| 32924774 | 25669 | 1002 |
| 33023668 | 25669 | 1003 |
| 33097422 | 25669 | 1004 |
| 33123314 | 25669 | 1017 |
| 33206129 | 25669 | 1002 |
| 33207634 | 25669 | 1002 |
| 33629198 | 25669 | 1002 |
| 33803833 | 25669 | 1002 |
| 34014787 | 25669 | 1004 |
| 34660663 | 25669 | 1003 |
| 35942322 | 25669 | 1007 |
| 38720505 | 25669 | 1002 |
| 39723719 | 25669 | 1001 |
| 40621938 | 25669 | 1008 |
| 41689393 | 25669 | 1001 |
| 41944750 | 25669 | 1007 |
| 42570652 | 25669 | 1001 |
| 42880361 | 25669 | 1 |
+----------+--------+---------+
即便如此运行起来还是慢:mysql> SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, tmp_E_role_info1.roleID, tmp_E_role_info1.related FROM `E_info` INNER JOIN tmp_E_role_info1 USING(infoID) WHERE tmp_E_role_info1.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 2;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
+----------+---------------------+--------+---------+
再列一遍explain:mysql> explain SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, tmp_E_role_info1.roleID, tmp_E_role_info1.related FROM `E_info` INNER JOIN tmp_E_role_info1 USING(infoID) WHERE tmp_E_role_info1.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 2;
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 7300143 | |
| 1 | SIMPLE | tmp_E_role_info1 | eq_ref | PRIMARY | PRIMARY | 7 | news_data.E_info.infoID,const | 1 | |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
| 1 | SIMPLE | E_info | ALL | PRIMARY | NULL | NULL | NULL | 7300143 | |
| 1 | SIMPLE | tmp_E_role_info1 | eq_ref | PRIMARY | PRIMARY | 7 | news_data.E_info.infoID,const | 1 | |
+----+-------------+------------------+--------+---------------+---------+---------+-------------------------------+---------+-------+
mysql> SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, tmp_E_role_info1.roleID, tmp_E_role_info1.related FROM `E_info` INNER JOIN tmp_E_role_info1 USING(infoID) WHERE tmp_E_role_info1.roleID = 25669;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 35942322 | 2008-12-15 16:10:12 | 25669 | 1007 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 1002 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 1001 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 1008 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 1001 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 1007 |
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
| 42880361 | 2009-04-18 08:58:28 | 25669 | 1 |
+----------+---------------------+--------+---------+
8 rows in set (53.60 sec)
mysql> EXPLAIN SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, tmp_E_role_info1.roleID, tmp_E_role_info1.related FROM `E_info` INNER JOIN tmp_E_role_info1 USING(infoID);
+----+-------------+------------------+------+---------------+---------+---------+-------------------------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------+---------+---------+-------------------------+---------+-------+
| 1 | SIMPLE | E_info | ALL | PRIMARY | NULL | NULL | NULL | 7300143 | |
| 1 | SIMPLE | tmp_E_role_info1 | ref | PRIMARY | PRIMARY | 4 | news_data.E_info.infoID | 1 | |
+----+-------------+------------------+------+---------------+---------+---------+-------------------------+---------+-------+
create index idx_E_role_info_roleID on E_role_info(roleID,infoID);然后用下面语句可以强制MySQL先做 E_role_info.roleID = 3 的筛选,然后再做连接mysql> desc E_role_info;
+---------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| infoID | int(11) | NO | PRI | NULL | |
| roleID | int(11) | NO | PRI | NULL | |
| related | int(11) | NO | | NULL | |
+---------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> desc E_info;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| infoID | int(11) | NO | PRI | NULL | |
| info_title | varchar(100) | NO | | NULL | |
| info_time | datetime | NO | | NULL | |
+------------+--------------+------+-----+---------+-------+
3 rows in set (0.03 sec)mysql> show index from E_role_info;
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 0 | PRIMARY | 1 | infoID | A | 59 | NULL | NULL | | BTREE | |
| E_role_info | 0 | PRIMARY | 2 | roleID | A | 119 | NULL | NULL | | BTREE | |
| E_role_info | 1 | idx_E_role_info_roleID | 1 | roleID | A | 10 | NULL | NULL | | BTREE | |
| E_role_info | 1 | idx_E_role_info_roleID | 2 | infoID | A | 119 | NULL | NULL | | BTREE | |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set (0.01 sec)mysql> show index from E_info;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A | 30 | NULL | NULL | | BTREE | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)mysql> explain select STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM E_role_info FORCE INDEX( idx_E_role_info_roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 3
-> ORDER BY E_info.infoID DESC LIMIT 3;
+----+-------------+-------------+--------+------------------------+------------------------+---------+-------------------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+------------------------+------------------------+---------+-------------------------+------+---------------------------------+
| 1 | SIMPLE | E_role_info | ref | idx_E_role_info_roleID | idx_E_role_info_roleID | 4 | const | 25 | Using temporary; Usingfilesort |
| 1 | SIMPLE | E_info | eq_ref | PRIMARY | PRIMARY | 4 | test.E_role_info.infoID | 1 | |
+----+-------------+-------------+--------+------------------------+------------------------+---------+-------------------------+------+---------------------------------+
2 rows in set (0.00 sec)mysql>
mysql> select b.infoID,b.info_time,a.roleID,a.related
-> from (
-> select roleID,related,infoID
-> from E_role_info
-> where roleID=25669) a inner join E_info b on a.infoID=b.infoID
-> order by b.info_time desc limit 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 1007 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 1001 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 1008 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 1001 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 1002 |
| 35942322 | 2008-12-15 16:10:12 | 25669 | 1007 |
| 34660663 | 2008-11-20 21:19:51 | 25669 | 1003 |
| 34014787 | 2008-11-08 14:09:59 | 25669 | 1004 |
| 33803833 | 2008-11-04 21:31:38 | 25669 | 1002 |
+----------+---------------------+--------+---------+
10 rows in set (0.05 sec)mysql>
-> select b.infoID,b.info_time,a.roleID,a.related
-> from (
-> select roleID,related,infoID
-> from E_role_info
-> where roleID=25669) a inner join E_info b on a.infoID=b.infoID
-> order by b.info_time desc limit 10;
+----+-------------+-------------+--------+---------------+---------+---------+----------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len |ref | rows | Extra |
+----+-------------+-------------+--------+---------------+---------+---------+----------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL |NULL | 45 | Using temporary; Using filesort |
| 1 | PRIMARY | b | eq_ref | PRIMARY | PRIMARY | 4 |a.infoID | 1 | |
| 2 | DERIVED | E_role_info | ref | roleID | roleID | 3 | | 55 | |
+----+-------------+-------------+--------+---------------+---------+---------+----------+------+---------------------------------+
3 rows in set (0.06 sec)mysql>
mysql> explain
-> select STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM E_role_info FORCE INDEX( roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 25669
-> ORDER BY E_info.infoID DESC LIMIT 3;
+----+-------------+-------------+--------+---------------+---------+---------+-------------------------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len |ref | rows | Extra |
+----+-------------+-------------+--------+---------------+---------+---------+-------------------------------+------+---------------------------------+
| 1 | SIMPLE | E_role_info | ref | roleID | roleID | 3 |const | 55 | Using temporary; Using filesort |
| 1 | SIMPLE | E_info | eq_ref | PRIMARY | PRIMARY | 4 |news_data2.E_role_info.infoID | 1 | |
+----+-------------+-------------+--------+---------------+---------+---------+-------------------------------+------+---------------------------------+
2 rows in set (0.05 sec)mysql> select STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM E_role_info FORCE INDEX( roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 25669
-> ORDER BY E_info.infoID DESC LIMIT 3;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 1007 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 1001 |
+----------+---------------------+--------+---------+
3 rows in set (0.05 sec)mysql>
+----+-------------+-------------+--------+---------------+---------+---------+----------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+---------------+---------+---------+----------+---------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 3089656 | Using temporary; Using filesort |
| 1 | PRIMARY | b | eq_ref | PRIMARY | PRIMARY | 4 | a.infoID | 1 | |
| 2 | DERIVED | E_role_info | ref | roleID | roleID | 3 | | 2895079 | |
+----+-------------+-------------+--------+---------------+---------+---------+----------+---------+---------------------------------+
3 rows in set (7.66 sec)mysql> select b.infoID,b.info_time,a.roleID,a.related from ( select roleID,related,infoID from E_role_info where roleID=413382) a inner join E_info b on a.infoID=b.infoID order by b.info_time desc limit 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880323 | 2009-04-18 08:58:56 | 413382 | 1004 |
| 42880311 | 2009-04-18 08:58:24 | 413382 | 1006 |
| 42880353 | 2009-04-18 08:58:21 | 413382 | 1004 |
| 42880348 | 2009-04-18 08:58:21 | 413382 | 1006 |
| 42880347 | 2009-04-18 08:58:21 | 413382 | 1004 |
| 42880351 | 2009-04-18 08:58:20 | 413382 | 1006 |
| 42880340 | 2009-04-18 08:57:59 | 413382 | 1004 |
| 42880288 | 2009-04-18 08:57:45 | 413382 | 1004 |
| 42880314 | 2009-04-18 08:57:31 | 413382 | 1005 |
| 42880306 | 2009-04-18 08:57:31 | 413382 | 1005 |
+----------+---------------------+--------+---------+
10 rows in set (34.35 sec)
mysql> EXPLAIN SELECT STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 17868847 | |
| 1 | SIMPLE | E_role_info | ref | infoID,roleID | infoID | 4 | news_data2.E_info.infoID | 6 | Using where |
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
2 rows in set (0.00 sec)这个看起来好像不错,type栏中一个是index一个是ref,但是E_info的rows的值太大了!实际运行起来确实也慢:mysql> SELECT STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 1007 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 1001 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 1008 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 1001 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 1002 |
| 35942322 | 2008-12-15 16:10:12 | 25669 | 1007 |
| 34660663 | 2008-11-20 21:19:51 | 25669 | 1003 |
| 34014787 | 2008-11-08 14:09:59 | 25669 | 1004 |
| 33803833 | 2008-11-04 21:31:38 | 25669 | 1002 |
+----------+---------------------+--------+---------+
10 rows in set (2 min 51.09 sec)我想,是不是E_info的主键infoID在join阶段没起到作用?
+----------+
| count(*) |
+----------+
| 3089656 |
+----------+
1 row in set (0.94 sec)mysql>
这种情况,换成人来决定,如何进行查询?
一种方法如下。
select b.infoID,b.info_time,a.roleID,a.related from ( select roleID,related,infoID from E_role_info where roleID=413382 order by infoID desc limit 10) a inner join E_info b on a.infoID=b.infoID order by b.info_
这样通过 select roleID,related,infoID from E_role_info where roleID=413382 order by infoID desc limit 10 只返回10条,速度应该可以提高。
但不幸的是,你的索引不对, 为了加快这个查询 where roleID=413382 order by infoID 需要一个 index (roleID,infoID)的索引mysql> show index from E_role_info;
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 1 | infoID | 1 | infoID | A | 13850305 | NULL | NULL | | BTREE | |
| E_role_info | 1 | roleID | 1 | roleID | A | 71639 | NULL | NULL | | BTREE | |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.05 sec)
这个确实挺快的,已经开始应用,呵呵!谢谢您了!不过,改为order by infoID 只是中间的权宜之计,最后还得改回order by info_time.
之所以目前改为order by infoID,是想看看join和order by统一了针对一个索引之后,是否能够很快。
可是还是不快!
mysql> EXPLAIN SELECT STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 17868847 | |
| 1 | SIMPLE | E_role_info | ref | infoID,roleID | infoID | 4 | news_data2.E_info.infoID | 6 | Using where |
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
2 rows in set (0.00 sec)mysql> SELECT STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 1001 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 1007 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 1001 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 1008 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 1001 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 1002 |
| 35942322 | 2008-12-15 16:10:12 | 25669 | 1007 |
| 34660663 | 2008-11-20 21:19:51 | 25669 | 1003 |
| 34014787 | 2008-11-08 14:09:59 | 25669 | 1004 |
| 33803833 | 2008-11-04 21:31:38 | 25669 | 1002 |
+----------+---------------------+--------+---------+
10 rows in set (2 min 51.09 sec)很疑惑的是,在这个问题中,即便infoID是主键,性能还是那么糟糕,而且在explain type那一栏显示了是index。
我现在很想知道,在这个sql语句中,主键没起作用吗?我想先解决order by infoID在这个语句中索引失效的问题,然后再慢慢解决order by info_time的问题!不知道思路对不对!
问题1:你是先做 `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID ,还是先做 WHERE E_role_info.roleID = 25669 ?
问题2:如果先做 WHERE E_role_info.roleID = 25669 这时候你会选择哪个索引 ? E_role_info(roleID)?
问题3:where 之后的结果集你已经有了。现在做 JOIN ,此时有哪些索引可以用? E_info (infoID) 主键。
总是4:JOIN完后,order by info_time 现在有什么索引可用吗? 无
问题1:你是先做 `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID ,还是先做 WHERE E_role_info.roleID = 25669 ?
答:应该先做WHERE E_role_info.roleID = 25669 这样可以在join阶段过滤大量没有必要的结果集!
问题2:如果先做 WHERE E_role_info.roleID = 25669 这时候你会选择哪个索引 ? E_role_info(roleID)?
答:没错,就我粗浅的水平来说,我会选择E_role_info(roleID)
问题3:where 之后的结果集你已经有了。现在做 JOIN ,此时有哪些索引可以用? E_info (infoID) 主键。
答:我认为,join会用到E_info(infoID)的索引,理由是,where的结果出来后,会遍历这个E_role_info.roleID = 25669 的结果集,遍历的过程中会针对每个E_role_info(infoID)去找到相应的E_info(infoID),这样的话应该是选择E_info(infoID)上的索引,这样会比较快!
总是4:JOIN完后,order by info_time 现在有什么索引可用吗? 无
答:是的,我也觉得无。可是现在为什么order by E_info.infoID的情况下E_info(infoID)也没有用呢?
这里我已经将ORDER BY info_time改为ORDER BY E_info.infoID,最后还是很慢!mysql> EXPLAIN SELECT STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 17868847 | |
| 1 | SIMPLE | E_role_info | ref | infoID,roleID | infoID | 4 | news_data2.E_info.infoID | 6 | Using where |
+----+-------------+-------------+-------+---------------+---------+---------+--------------------------+----------+-------------+
2 rows in set (0.00 sec)
mysql> show index from E_info;
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A |17868847 | NULL | NULL | | BTREE | |
| E_info | 1 | info_time | 1 | info_time | A | 8934423 | NULL | NULL | | BTREE | |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.05 sec)mysql> show index from E_role_info;
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 1 | infoID | 1 | infoID | A | 13850305 | NULL | NULL | | BTREE | |
| E_role_info | 1 | roleID | 1 | roleID | A | 71639 | NULL | NULL | | BTREE | |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.03 sec)mysql>我们看一下MySQL会怎么执行? SELECT STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID
WHERE E_role_info.roleID = 25669
ORDER BY E_info.infoID
DESC LIMIT 0 , 10;由于 E_role_info.roleID 的 Cardinality = 71639, 而你有记录 83101830 行, 所以MySQL会直接先进行 `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 17868847 | |
此时会用到 E_info 的 PRIMARY 然后会用到 E_role_info.infoID
| 1 | SIMPLE | E_role_info | ref | infoID,roleID | infoID | 4 | news_data2.E_info.infoID | 6 | Using where |和问题4相同。 JOIN完后,order by infoID 现在有什么索引可用吗? 无
昨天晚上就开始弄,主要是E_role_info(infoID, roleID)含有大量的重复,还得过滤重复内容!下面我列一下新的测试结果(语句还是上边那个语句):
mysql> show index from E_info;
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_info | 0 | PRIMARY | 1 | infoID | A | 17868847 | NULL | NULL | | BTREE | |
| E_info | 1 | info_time | 1 | info_time | A | 8934423 | NULL | NULL | | BTREE | |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)mysql> show index from E_role_info;
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| E_role_info | 0 | PRIMARY | 1 | infoID | A | NULL | NULL | NULL | | BTREE | |
| E_role_info | 0 | PRIMARY | 2 | roleID | A | 82797994 | NULL | NULL | | BTREE | |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)mysql> EXPLAIN SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----+-------------+-------------+--------+---------------+---------+---------+--------------------------------+----------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+---------------+---------+---------+--------------------------------+----------+-------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 17868847 | |
| 1 | SIMPLE | E_role_info | eq_ref | PRIMARY | PRIMARY | 7 | news_data2.E_info.infoID,const | 1 | |
+----+-------------+-------------+--------+---------------+---------+---------+--------------------------------+----------+-------+
2 rows in set (0.00 sec)mysql> set profiling = 1;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 0 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 0 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 0 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 0 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 0 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 0 |
| 35942322 | 2008-12-15 16:10:12 | 25669 | 0 |
| 34660663 | 2008-11-20 21:19:51 | 25669 | 0 |
| 34014787 | 2008-11-08 14:09:59 | 25669 | 0 |
| 33803833 | 2008-11-04 21:31:38 | 25669 | 0 |
+----------+---------------------+--------+---------+
10 rows in set (1 min 14.45 sec)mysql> show profile;
+--------------------------------+-----------+
| Status | Duration |
+--------------------------------+-----------+
| (initialization) | 0.000002 |
| checking query cache for query | 0.0000900 |
| Opening tables | 0.000011 |
| System lock | 0.000005 |
| Table lock | 0.000008 |
| init | 0.000023 |
| optimizing | 0.000015 |
| statistics | 0.00002 |
| preparing | 0.000016 |
| executing | 0.000003 |
| Sorting result | 0.000003 |
| Sending data | 74.450095 |
| end | 0.000008 |
| query end | 0.000003 |
| freeing items | 0.00001 |
| closing tables | 0.000004 |
| logging slow query | 0.000002 |
+--------------------------------+-----------+
17 rows in set (0.01 sec)
哦,原来会根据Cardinality 这个值来改变顺序啊!
mysql> show index from E_role_info;
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+-
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+-
| E_role_info | 0 | PRIMARY | 1 | infoID | A | NULL |
| E_role_info | 0 | PRIMARY | 2 | roleID | A | 82797994 |
| E_role_info | 1 | idx_E_role_info_roleID | 1 | roleID | A | 71624 |
| E_role_info | 1 | idx_E_role_info_roleID | 2 | infoID | A | 82797994 |
+-------------+------------+------------------------+--------------+-------------+-----------+-------------+-
4 rows in set (0.05 sec)mysql> explain
-> select roleID,related,infoID
-> from E_role_info
-> where roleID=413382
-> order by infoID
-> desc limit 10 ;
+----+-------------+-------------+------+------------------------+------------------------+---------+-------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+------------------------+------------------------+---------+-------+---------+-------------+
| 1 | SIMPLE | E_role_info | ref | idx_E_role_info_roleID | idx_E_role_info_roleID | 3 | const | 2753512 | Using where |
+----+-------------+-------------+------+------------------------+------------------------+---------+-------+---------+-------------+
1 row in set (0.03 sec)mysql> select roleID,related,infoID
-> from E_role_info
-> where roleID=413382
-> order by infoID
-> desc limit 10 ;
+--------+---------+----------+
| roleID | related | infoID |
+--------+---------+----------+
| 413382 | 0 | 42880359 |
| 413382 | 0 | 42880353 |
| 413382 | 0 | 42880351 |
| 413382 | 0 | 42880348 |
| 413382 | 0 | 42880347 |
| 413382 | 0 | 42880341 |
| 413382 | 0 | 42880340 |
| 413382 | 0 | 42880339 |
| 413382 | 0 | 42880338 |
| 413382 | 0 | 42880336 |
+--------+---------+----------+
10 rows in set (0.05 sec)mysql>这样,速度应该没问题了,但如果想解决 order by info_time 仍是不行。关键是要先能够人为的发现一条查找的路径。
+----+-------------+-------------+-------+------------------------+------------------------+---------+--------------------------------+----------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+------------------------+------------------------+---------+--------------------------------+----------+-------+
| 1 | SIMPLE | E_info | index | PRIMARY | PRIMARY | 4 | NULL | 17868847 | |
| 1 | SIMPLE | E_role_info | ref | idx_E_role_info_roleID | idx_E_role_info_roleID | 7 | const,news_data2.E_info.infoID | 1 | |
+----+-------------+-------------+-------+------------------------+------------------------+---------+--------------------------------+----------+-------+
2 rows in set (0.00 sec)mysql> SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM `E_info` INNER JOIN E_role_info FORCE INDEX(idx_E_role_info_roleID) ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 25669 ORDER BY E_info.infoID DESC LIMIT 0 , 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 0 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 0 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 0 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 0 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 0 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 0 |
| 35942322 | 2008-12-15 16:10:12 | 25669 | 0 |
| 34660663 | 2008-11-20 21:19:51 | 25669 | 0 |
| 34014787 | 2008-11-08 14:09:59 | 25669 | 0 |
| 33803833 | 2008-11-04 21:31:38 | 25669 | 0 |
+----------+---------------------+--------+---------+
10 rows in set (1 min 13.66 sec)为什么我这还不行?在查询25669的时候?不过,这个时间倒是比以前的4分多钟快多了!确实是门学问啊,呵呵!
-> select SQL_NO_CACHE STRAIGHT_JOIN
-> E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM E_role_info FORCE INDEX( idx_E_role_info_roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 25669
-> ORDER BY E_info.infoID DESC LIMIT 10;
+----+-------------+-------------+--------+------------------------+------------------------+---------+-------------------------------+------+---
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Ex
+----+-------------+-------------+--------+------------------------+------------------------+---------+-------------------------------+------+---
| 1 | SIMPLE | E_role_info | ref | idx_E_role_info_roleID | idx_E_role_info_roleID | 3 | const | 40 | Us
| 1 | SIMPLE | E_info | eq_ref | PRIMARY | PRIMARY | 4 | news_data2.E_role_info.infoID | 1 |
+----+-------------+-------------+--------+------------------------+------------------------+---------+-------------------------------+------+---
2 rows in set (0.05 sec)mysql> select SQL_NO_CACHE STRAIGHT_JOIN
-> E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM E_role_info FORCE INDEX( idx_E_role_info_roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 25669
-> ORDER BY E_info.infoID DESC LIMIT 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42570652 | 2009-04-14 13:27:45 | 25669 | 0 |
| 41944750 | 2009-04-03 20:22:06 | 25669 | 0 |
| 41689393 | 2009-03-31 18:50:38 | 25669 | 0 |
| 40621938 | 2009-03-17 19:46:21 | 25669 | 0 |
| 39723719 | 2009-03-03 06:56:16 | 25669 | 0 |
| 38720505 | 2009-02-13 17:19:20 | 25669 | 0 |
| 35942322 | 2008-12-15 16:10:12 | 25669 | 0 |
| 34660663 | 2008-11-20 21:19:51 | 25669 | 0 |
| 34014787 | 2008-11-08 14:09:59 | 25669 | 0 |
| 33803833 | 2008-11-04 21:31:38 | 25669 | 0 |
+----------+---------------------+--------+---------+
10 rows in set (1.00 sec)mysql>
所以,您一直在考虑如何优化这个语句:SELECT SQL_NO_CACHE STRAIGHT_JOIN
E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
FROM E_role_info FORCE INDEX( idx_E_role_info_roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
WHERE E_role_info.roleID = 25669
ORDER BY E_info.infoID DESC LIMIT 10;而我一直抓住E_info表中的主键为什么不起作用而不放!
在琢磨:SELECT SQL_NO_CACHE STRAIGHT_JOIN
E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
FROM `E_info` INNER JOIN E_role_info FORCE INDEX(idx_E_role_info_roleID) ON E_info.infoID = E_role_info.infoID
WHERE E_role_info.roleID = 25669
ORDER BY E_info.infoID DESC LIMIT 0 , 10;
用先生您提供的语句查413382时也还慢!mysql> SELECT SQL_NO_CACHE STRAIGHT_JOIN E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related FROM E_role_info FORCE INDEX( idx_E_role_info_roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID WHERE E_role_info.roleID = 413382 ORDER BY E_info.infoID DESC LIMIT 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880359 | 2009-04-18 07:54:14 | 413382 | 0 |
| 42880353 | 2009-04-18 08:58:21 | 413382 | 0 |
| 42880351 | 2009-04-18 08:58:20 | 413382 | 0 |
| 42880348 | 2009-04-18 08:58:21 | 413382 | 0 |
| 42880347 | 2009-04-18 08:58:21 | 413382 | 0 |
| 42880341 | 2009-04-18 06:23:47 | 413382 | 0 |
| 42880340 | 2009-04-18 08:57:59 | 413382 | 0 |
| 42880339 | 2009-04-18 07:58:28 | 413382 | 0 |
| 42880338 | 2009-04-18 06:23:47 | 413382 | 0 |
| 42880336 | 2009-04-18 06:23:47 | 413382 | 0 |
+----------+---------------------+--------+---------+
10 rows in set (33.43 sec)
现在我的困扰还是413382,25669这两个值不可兼得!
总之在我的应用中,413382,25669这两个值恰好反映了我们系统中两个极端的情况,我也不知道是否能够达到一个平衡,使得查询这两个值都能够很迅速!这两天也很急躁,不过跟着您的思路也学到了不少知识,非常感谢!现在我就顺着您的思路走,这样应该会更有效!
-> E_info.infoID, E_info.info_time, E_role_info.roleID, E_role_info.related
-> FROM E_role_info FORCE INDEX( idx_E_role_info_roleID ) INNER JOIN `E_info` ON E_info.infoID = E_role_info.infoID
-> WHERE E_role_info.roleID = 413382
-> ORDER BY E_role_info.infoID DESC LIMIT 10;
+----------+---------------------+--------+---------+
| infoID | info_time | roleID | related |
+----------+---------------------+--------+---------+
| 42880359 | 2009-04-18 07:54:14 | 413382 | 0 |
| 42880353 | 2009-04-18 08:58:21 | 413382 | 0 |
| 42880351 | 2009-04-18 08:58:20 | 413382 | 0 |
| 42880348 | 2009-04-18 08:58:21 | 413382 | 0 |
| 42880347 | 2009-04-18 08:58:21 | 413382 | 0 |
| 42880341 | 2009-04-18 06:23:47 | 413382 | 0 |
| 42880340 | 2009-04-18 08:57:59 | 413382 | 0 |
| 42880339 | 2009-04-18 07:58:28 | 413382 | 0 |
| 42880338 | 2009-04-18 06:23:47 | 413382 | 0 |
| 42880336 | 2009-04-18 06:23:47 | 413382 | 0 |
+----------+---------------------+--------+---------+
10 rows in set (0.06 sec)mysql>