在文章开始之前,我先推荐一篇讲聚集索引、非聚集索引(也叫辅助索引)、覆盖索引的文章,算是比较通俗易懂的,就当是温习了。
https://blog.csdn.net/itguangit/article/details/82145322#
总结起来3句话:
CREATE TABLE `users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`email` VARCHAR(100) NOT NULL,
`email_verified_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`password` VARCHAR(255) NULL DEFAULT NULL,
`remember_token` VARCHAR(20) NULL DEFAULT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`score` DECIMAL(10,4) NULL DEFAULT '0.0000',
`cate_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
delimiter //
create function rand_string1(n INT)
returns varchar(255) charset utf8
begin
declare chars_str varchar (100) default 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
declare return_str varchar (255) default '';
declare i int default 0;
while i < n do
set return_str = concat(return_str,substring(chars_str, floor(1+ rand() * 52), 1));
set i = i + 1;
end while;
return return_str;
end //
delimiter ;
delimiter //
create function getTime()
returns timestamp
begin
return ( select concat( 2009+floor(rand()*10) ,'-',lpad(1+floor(rand()*11),2,0),'-',floor(1+rand()*28),' ', floor(8+rand()*10),':',floor(10+rand()*49),':',floor(10+rand()*49)) );
END //
delimiter ;
delimiter //
CREATE PROCEDURE insert_users(IN start int(10), IN max_num int(10))
begin
declare i int default 0;
set autocommit = 0;
repeat
set i = i+1;
insert into users(name,email,password,remember_token,created_at,score,cate_id)
values(rand_string(20), rand_string(30), rand_string(64), rand_string(20), getTime(), 50+floor(rand()*50), floor(rand()*100) );
until i = max_num
end repeat;
commit;
end //
delimiter ;
call insert_users(0,10000000);
Query OK, 0 rows affected (2 hours 48 min 13.58 sec)
mysql> select * from users limit 1 offset 100000;
1 row in set (0.28 sec)
mysql> select * from users limit 1 offset 1000000;
1 row in set (0.75 sec)
mysql> select * from users limit 1 offset 5000000;
1 row in set (3.71 sec)
mysql> explain select * from users limit 15 offset 5000000;
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
| 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | NULL | 8909863 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
| 10000030 |
+----------+
1 row in set (17.12 sec)