我正在一个数据库庞大的网站上工作。当时表中有100万条记录。当我执行查询时,执行需要太多时间。下面给出了一个示例查询:
select * from `ratings` order by id limit 499500, 500
每个查询都需要超过一分钟,但是当我将表格删除到1万条记录时,此查询会快速执行。
正如我所读到的,表中的100万条记录没有问题,因为在数据库表中,没有大记录的问题。
我已经在Stack Overflow问题 How do I add indices to MySQL tables? 的帮助下使用了表格中的id索引,但我仍然遇到了同样的问题。
***我正在使用CodeIgniter进行项目。
答案 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列上有一个索引。
有许多因素也会影响您的查询效果:
还有更多......
按照以下链接获取执行计划并确定性能降级因素: http://www.sitepoint.com/using-explain-to-write-better-mysql-queries/
How to optimise MySQL queries based on EXPLAIN plan
如果您遇到任何麻烦,请告诉我。
答案 2 :(得分:1)
清单:
替代方法是尝试使用活动索引进行查询:
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
此外,如果您对搜索条件有疑问,请确保将常用列编入索引。