2015-09-01 30 views
1
# Query_time: 11.041339 Lock_time: 0.000074 Rows_sent: 1 Rows_examined: 4033514 
use mytable; 
SET timestamp=1441090564; 
select c.fetching_method,cc.book_chapter_id,cc.book_episode_name,cc.book_episode_number,cc.book_id, 
ccc.book_image_path,ccc.book_page_sequence,cccc.book_name,cccc.book_permalink 
     from book_source c, book_chapter cc,book_page ccc,book cccc 
     where c.book_source_id = cc.book_source_id AND cc.book_chapter_id = ccc.book_chapter_id AND cccc.book_id = cc.book_id AND 
     cccc.book_permalink='Dancing_Cow' AND cc.book_episode_number > '42' ORDER BY book_episode_number ASC LIMIT 1; 


mysql> desc book; 
+--------------------+------------------+------+-----+---------+----------------+ 
| Field    | Type    | Null | Key | Default | Extra   | 
+--------------------+------------------+------+-----+---------+----------------+ 
| book_id   | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| description  | text    | YES |  | NULL |    | 
| book_picture  | text    | YES |  | NULL |    | 
| book_permalink | text    | YES |  | NULL |    | 
| total_view_count | int(16)   | NO |  | 0  |    | 
| thumbnail   | int(2)   | YES |  | NULL |    | 
| book_rating  | double   | YES |  | NULL |    | 
| fail_retry   | int(2)   | NO |  | 0  |    | 
+--------------------+------------------+------+-----+---------+----------------+ 
18 rows in set (0.01 sec) 

mysql> desc book_page; 
+---------------------+------------------+------+-----+---------+----------------+ 
| Field    | Type    | Null | Key | Default | Extra   | 
+---------------------+------------------+------+-----+---------+----------------+ 
| book_page_id  | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| book_chapter_id | int(10)   | YES |  | NULL |    | 
| book_image_path | text    | YES |  | NULL |    | 
| book_page_sequence | double   | YES |  | NULL |    | 
| date_time_added  | text    | YES |  | NULL |    | 
| date_time_modified | text    | YES |  | NULL |    | 
| watermark   | int(2)   | YES |  | NULL |    | 
| book_related  | text    | YES |  | NULL |    | 
+---------------------+------------------+------+-----+---------+----------------+ 
8 rows in set (0.00 sec) 

mysql> desc book_source; 
+--------------------+------------------+------+-----+---------+----------------+ 
| Field    | Type    | Null | Key | Default | Extra   | 
+--------------------+------------------+------+-----+---------+----------------+ 
| book_source_id | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| book_id   | int(10)   | YES |  | NULL |    | 
| book_source_url | varchar(150)  | YES | UNI | NULL |    | 
| fetching_method | text    | YES |  | NULL |    | 
| source_book_name | text    | YES |  | NULL |    | 
| process_id   | int(10)   | YES |  | NULL |    | 
| disable   | int(1)   | YES |  | NULL |    | 
| source_group  | int(2)   | YES |  | NULL |    | 
| fail_retry   | int(2)   | YES |  | 0  |    | 
+--------------------+------------------+------+-----+---------+----------------+ 
11 rows in set (0.00 sec) 

mysql> desc book_chapter; 
+----------------------+------------------+------+-----+---------+----------------+ 
| Field    | Type    | Null | Key | Default | Extra   | 
+----------------------+------------------+------+-----+---------+----------------+ 
| book_chapter_id  | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| book_view_count  | int(10)   | YES |  | NULL |    | 
| book_episode_number | double   | YES |  | NULL |    | 
| book_episode_name | text    | YES |  | NULL |    | 
| book_source_id  | int(10)   | YES |  | NULL |    | 
| book_id    | int(20)   | YES |  | NULL |    | 
| book_complete  | text    | YES |  | NULL |    | 
| total_pages   | double   | YES |  | NULL |    | 
| chapter_view_count | int(16)   | NO |  | 0  |    | 
| book_fix   | int(2)   | YES |  | NULL |    | 
| original_url   | text    | YES |  | NULL |    | 
+----------------------+------------------+------+-----+---------+----------------+ 
13 rows in set (0.00 sec) 

我有一个非常坏的连接语句引起我的服务器上沉重的负担。 有没有一种方法可以改进此联合声明以使用较少的行。Mysql的使用超过400多万行获得1个查询

我的这张表book_page有大约1米的记录。我怎么能优化到真正能够绘制数据而不使用那么多记录(4米),因为我想要的数据实际上很少。只有很少的值

回答

1

您应该始终做的第一件事是使用explain select..来查看查询健康状况以及优化器如何处理查询。这会给你一些重要的信息,比如你在表中缺少索引,产生全表扫描等。

现在我会使用显式连接语法而不是隐式来编写查询,而您正在使用查询看起来像

select 
c.fetching_method, 
cc.book_chapter_id, 
cc.book_episode_name, 
cc.book_episode_number, 
cc.book_id, 
ccc.book_image_path, 
ccc.book_page_sequence, 
cccc.book_name, 
cccc.book_permalink 
from book_source c 
join book_chapter cc on cc.book_source_id = c.book_source_id 
join book_page ccc on ccc.book_chapter_id = cc.book_chapter_id 
join book cccc on cccc.book_id = cc.book_id 
where 
cccc.book_permalink='Dancing_Cow' 
AND cc.book_episode_number > '42' 
ORDER BY cc.book_episode_number ASC LIMIT 1; 

现在,您需要检查表是具有适当的索引,注意主键总是索引,所以你不需要再添加它们,但是从上面的查询,你可以有以下指标在表中

alter table book_chapter add index src_eps_idx(book_source_id,book_episode_number); 

alter table book_page add index book_chapter_id_idx(book_chapter_id); 

alter table book add index id_permalink_idx(book_id,book_permalink); 

请注意,如果已在book_page表上编入索引,则可以跳过该表,更重要的是 - 在应用索引之前对表进行备份。

0

我会从使用EXPLAIN语句开始,找出查询出了什么问题。有些问题我会问自己:

  1. 有没有列上定义的索引在WHEREORDER BY子句中使用?
  2. ORDER BY通常是一面红旗。如果订购很重要,我宁愿有一个已经按照必要的顺序订购的索引(在这种情况下为ASC)。 More here。在这里使用排序索引还有第二个优点:在WHERE子句中的一个中,有一个> 42子句。如果没有排序索引,数据库必须遍历整个索引才能获取所有匹配的行。通过排序索引,这将更快。