MySQL语句需要超过一分钟才能执行

时间:2015-11-12 07:09:22

标签: php mysql

我正在一个数据库庞大的网站上工作。当时表中有100万条记录。当我执行查询时,执行需要太多时间。下面给出了一个示例查询:

select * from `ratings` order by id limit 499500, 500

每个查询都需要超过一分钟,但是当我将表格删除到1万条记录时,此查询会快速执行。

正如我所读到的,表中的100万条记录没有问题,因为在数据库表中,没有大记录的问题。

我已经在Stack Overflow问题 How do I add indices to MySQL tables? 的帮助下使用了表格中的id索引,但我仍然遇到了同样的问题。

***我正在使用CodeIgniter进行项目。

6 个答案:

答案 0 :(得分:15)

注意,这并不是建议使用MyISAM一分钟。我只是用它来得到我的id,min,max和count来排队。所以请忽略引擎。

create table ratings
(   id int auto_increment primary key,
    thing int null
)engine=MyISAM;
insert ratings (thing) values (null),(null),(null),(null),(null),(null),(null),(null),(null);
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;

insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;

insert ratings (thing) select thing from ratings;
insert ratings (thing) select thing from ratings;

我现在有4.7M行

select count(*),min(id),max(id) from ratings;
+----------+---------+---------+
| count(*) | min(id) | max(id) |
+----------+---------+---------+
|  4718592 |       1 | 4718592 |
+----------+---------+---------+
select * from `ratings` order by id limit 499500, 500;
-- 1 second on a dumpy laptop

explain select * from `ratings` order by id limit 499500, 500;
+----+-------------+---------+------+---------------+------+---------+------+---------+----------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows    | Extra          |
+----+-------------+---------+------+---------------+------+---------+------+---------+----------------+
|  1 | SIMPLE      | ratings | ALL  | NULL          | NULL | NULL    | NULL | 4718592 | Using filesort |
+----+-------------+---------+------+---------------+------+---------+------+---------+----------------+

explain select * from `ratings` where id>=499501 limit 500;
+----+-------------+---------+-------+---------------+---------+---------+------+---------+-----------------------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows    | Extra                 |
+----+-------------+---------+-------+---------------+---------+---------+------+---------+-----------------------+
|  1 | SIMPLE      | ratings | range | PRIMARY       | PRIMARY | 4       | NULL | 4198581 | Using index condition |
+----+-------------+---------+-------+---------------+---------+---------+------+---------+-----------------------+

故事的道德可能是使用where子句。

人们不能排除陷入僵局的可能性。

答案 1 :(得分:1)

首先检查查询的执行计划以确定瓶颈,并在需要时创建索引。我认为你至少应该在Id列上有一个索引。

有许多因素也会影响您的查询效果:

  1. 数据页的碎片
  2. 未更新的表格统计
  3. 许多请求并行运行
  4. 还有更多......

    按照以下链接获取执行计划并确定性能降级因素: http://www.sitepoint.com/using-explain-to-write-better-mysql-queries/

    How to optimise MySQL queries based on EXPLAIN plan

    如果您遇到任何麻烦,请告诉我。

答案 2 :(得分:1)

清单:

  • 通过ASC
  • 在'id'列顺序上创建聚集索引(索引)
  • 从命令行see this
  • 检查查询时间
  • 检查您的PHP代码(我看到您使用 CodeIgniter )。关于您的算法:您是否使用了CodeIgniter数据库see this?如果您使用的是原始查询,请检查您的循环。

替代方法是尝试使用活动索引进行查询:

select * from `ratings` where id>=456789 limit 500;

答案 3 :(得分:0)

检查索引。每个表中都应该有一个主键 并且查询的where子句中可能存在不属于主索引或聚簇索引的属性。

答案 4 :(得分:-1)

这是Tuts-plus的链接,可以帮助您解决问题。

最可能的解决方案是索引数据库,而不是(*)使用列名Better way to Query

答案 5 :(得分:-1)

如果您使用的是InnoDB引擎,请将其更改为MyISAM。读取操作更快。 When to use MyISAM and InnoDB

此外,如果您对搜索条件有疑问,请确保将常用列编入索引。