Mysql 使用超过 400 万行来获取 1 个查询

标签 mysql

# 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)

我有一个非常糟糕的连接语句,导致我的服务器负载过重。 有什么方法可以改进此连接语句以使用较少的行。

我的这张表 book_page 有大约 100 万条记录。我如何优化才能真正能够绘制数据而不使用那么多记录(4m),因为我想要的数据实际上很少。就这么点值(value)

最佳答案

您应该始终做的第一件事是使用 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_chapter_id 已在 book_page 表上建立索引,您可以跳过这一步,更重要的是 - 在应用索引之前备份表。

关于Mysql 使用超过 400 万行来获取 1 个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32325591/

相关文章:

mysql - 如何忽略 MySQL 5.6 的小数秒?

mysql - 当 ON 语句为 false 时表连接是否有效?

mysql - 当复选框被选中时如何将表单数据插入到mysql?

MYSQL连接大字符串

mysql - 为什么oracle可以update pk=pk+1,而MySQL不能update set pk=pk+1

mysql - 简单的 SQL 查询工作台

mysql - 我怎样才能在MySQL的这张表中度过那几周呢?

php - MySQL+Php服务器最多能有多少个并发连接?

php - 如何使用PHP在多个下拉表单数据库中显示相同的记录?

php - MySQL 返回相反的值