闲来无聊今天探讨一下Mysql百万级下的分页问题!本文由张大妈比价(hizdm.com)强力推荐!
首先先写了一段简单的生成数据程序:
$mysql_server_name = 'localhost';
$mysql_username = 'root';
$mysql_password = 'mysql';
$mysql_database = 'mysql_page';
$conn = mysql_connect($mysql_server_name, $mysql_username, $mysql_password);
mysql_query("set names 'utf8'", $conn);
mysql_select_db($mysql_database, $conn);
$pre_time = time();
$sql = "('title-0000', 'content-0000', $pre_time)";
for ($i=0; $i < 1000000; $i++) {
$title = 'title-' . $i;
$content = 'content-' . $i;
$create_time = time();
$sql .= ",('{$title}', '{$content}', $create_time)";
}
$sql = "insert into news (title
, content
, create_time
) values $sql";
$result = mysql_query($sql, $conn);
var_dump($result);
mysql_close();
我们通常的做法是select * from news limit 1,10;这样查询是很快的但是前提是数据量不大的情况下,如果要是这样select * from news limit 1000000,10;呢,下图为执行词条语句的结果,耗时0.69S;
select * from news order by id limit 1000000,10这样的查询耗时为0.61S,这次比上一次查询时间确实是短了,短的但是不够明显.
select * from news where id between 1000001 and 1000010;这样查询的的耗时为0.00S,这次查询和上两种查询明显不是一个级别.
接 下来继续执行 select * from news where id in (1000001, 1000002, 1000003, 1000004, 1000005, 1000006, 1000007, 1000008, 1000009, 1000010);结果查询耗时也是0.00S;
接下来就分析一下:
第一个查询没有用索引而且索引的类型是ALL,第二个查询用的是主键索引索引的类型是index,第三个查询和第四个查询都是用的主键索引并且类型都是rank,截图分别如下:
Explain的各个属性的含义如下:
id
select查询的序列号
select_type
select查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询。
table
输出的行所引用的表。
type
联合查询所使用的类型。
type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。
possible_keys
指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段不是适合索引。
key
显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL。
key_len
显示MySQL决定使用的键长度。如果键是NULL,长度就是NULL。文档提示特别注意这个值可以得出一个多重主键里mysql实际使用了哪一部分。
ref
显示哪个字段或常数与key一起被使用。
rows
这个数表示mysql要遍历多少数据才能找到,在innodb上是不准确的。
Extra
如果是Only index,这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不着where,一般就是没查出来啥。
如 果此信息显示Using filesort或者Using temporary的话会很吃力,WHERE和ORDER BY的索引经常无法兼顾,如果按照WHERE来确定索引,那么在ORDER BY时,就必然会引起Using filesort,这就要看是先过滤再排序划算,还是先排序再过滤划算。
由以上分析可知,在用mysql大数据进行分页的时候尽量用between和in进行分页即可!
如果数据有频繁的删除就需要找出相应的id,以及有更多的搜索条件时,下次再做分析!
张大妈比价(Hizdm.com) - 一个纯粹的比价网站....仅此而已!