大数据MySQL分库后如何高效精确地合并数据库节点结果集进行分页查询的通杀方案


USE testdb; -- 分3个表存储用户信息
CREATE TABLE `users0` (
  `user_id` BIGINT(20) NOT NULL,
  `user_name` VARCHAR(100) NOT NULL,
  `email` VARCHAR(120) NOT NULL,
  `password` VARCHAR(60) NOT NULL,
  `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `last_modified` TIMESTAMP(6) NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

CREATE TABLE `users1` (
  `user_id` BIGINT(20) NOT NULL,
  `user_name` VARCHAR(100) NOT NULL,
  `email` VARCHAR(120) NOT NULL,
  `password` VARCHAR(60) NOT NULL,
  `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `last_modified` TIMESTAMP(6) NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

CREATE TABLE `users2` (
  `user_id` BIGINT(20) NOT NULL,
  `user_name` VARCHAR(100) NOT NULL,
  `email` VARCHAR(120) NOT NULL,
  `password` VARCHAR(60) NOT NULL,
  `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `last_modified` TIMESTAMP(6) NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 初始化3个表的记录 
DELIMITER $$

USE `testdb`$$

DROP PROCEDURE IF EXISTS `generateInitData`$$

CREATE DEFINER=`root`@`%` PROCEDURE `generateInitData`(totalRows INT)
BEGIN
	SET @num = 0;
	WHILE @num < totalRows DO
		SET @user_id = @num;
		SET @user_name = CONCAT('test', @user_id);
		SET @email = CONCAT(@user_name, '@163.com');
		SET @password = FLOOR(RAND() * 1000000);
		SET @created_at = CURRENT_TIMESTAMP(6);
		SET @current = @num % 3;
		IF @current = 0 THEN
			INSERT INTO users0(`user_id`,`user_name`,`email`,`password`,`created_at`) VALUES(@user_id,@user_name,@email,@password,@created_at);
		ELSEIF @current = 1 THEN
			INSERT INTO users1(`user_id`,`user_name`,`email`,`password`,`created_at`) VALUES(@user_id,@user_name,@email,@password,@created_at);
		ELSEIF @current = 2 THEN
			INSERT INTO users2(`user_id`,`user_name`,`email`,`password`,`created_at`) VALUES(@user_id,@user_name,@email,@password,@created_at);
		END IF;
		SET @num = @num + 1;
	END WHILE;
END$$

DELIMITER ;
-- 调用存储过程初始化100万条记录 
CALL generateInitData(1000000)


1 queries executed, 1 success, 0 errors, 0 warnings

查询:call generateInitData(1000000)

共 1000000 行受到影响

执行耗时   : 5 min 36 sec
传送时间   : 0 sec
总耗时      : 5 min 36 sec
$ mysql -uroot -h192.168.10.10 -p123456
USE testdb0; -- 分3个数据库存储用户信息(分库不分表)
CREATE TABLE `users` (
  `user_id` BIGINT(20) NOT NULL,
  `user_name` VARCHAR(100) NOT NULL,
  `email` VARCHAR(120) NOT NULL,
  `password` VARCHAR(60) NOT NULL,
  `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `last_modified` TIMESTAMP(6) NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


$ mysql -uroot -h192.168.10.11 -p123456
USE testdb1; -- 分3个数据库存储用户信息(分库不分表)
CREATE TABLE `users` (
  `user_id` BIGINT(20) NOT NULL,
  `user_name` VARCHAR(100) NOT NULL,
  `email` VARCHAR(120) NOT NULL,
  `password` VARCHAR(60) NOT NULL,
  `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `last_modified` TIMESTAMP(6) NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


$ mysql -uroot -h192.168.10.12 -p123456
USE testdb2; -- 分3个数据库存储用户信息(分库不分表)
CREATE TABLE `users` (
  `user_id` BIGINT(20) NOT NULL,
  `user_name` VARCHAR(100) NOT NULL,
  `email` VARCHAR(120) NOT NULL,
  `password` VARCHAR(60) NOT NULL,
  `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `last_modified` TIMESTAMP(6) NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

使用MySQL 客户端可视化管理工具SQLyog Ultimate 将数据库 testdb 中3个表 users0,users1,users2分别导出对应保存

为users0.csv ,users1.csv ,users2.csv 这3个csv格式的文件(文件大小均为23.3Mb大小)

同样使用SQLyog,然后将文件users0.csv导入到数据库服务器节点192.168.10.10 数据库表名称为testdb0.users中;

同样使用SQLyog,然后将文件users1.csv导入到数据库服务器节点192.168.10.11 数据库表名称为testdb1.users中;

同样使用SQLyog,然后将文件users2.csv导入到数据库服务器节点192.168.10.12 数据库表名称为testdb2.users中;

第1个数据库节点

$ mysql -uroot -h192.168.10.10 -p123456
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 25
Server version: 10.3.10-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use testdb0
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 0,30;  -- 第1页,每页30行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|       0 | test0     | [email protected]  | 723968   | 2018-10-30 00:45:03.120618 | NULL          |
|       3 | test3     | [email protected]  | 623938   | 2018-10-30 00:45:03.123731 | NULL          |
|       6 | test6     | [email protected]  | 367932   | 2018-10-30 00:45:03.125267 | NULL          |
|       9 | test9     | [email protected]  | 588289   | 2018-10-30 00:45:03.126534 | NULL          |
|      12 | test12    | [email protected] | 129007   | 2018-10-30 00:45:03.127923 | NULL          |
|      15 | test15    | [email protected] | 436787   | 2018-10-30 00:45:03.130163 | NULL          |
|      18 | test18    | [email protected] | 459812   | 2018-10-30 00:45:03.131413 | NULL          |
|      21 | test21    | [email protected] | 991766   | 2018-10-30 00:45:03.132423 | NULL          |
|      24 | test24    | [email protected] | 926347   | 2018-10-30 00:45:03.133656 | NULL          |
|      27 | test27    | [email protected] | 330094   | 2018-10-30 00:45:03.134957 | NULL          |
|      30 | test30    | [email protected] | 396205   | 2018-10-30 00:45:03.135756 | NULL          |
|      33 | test33    | [email protected] | 783877   | 2018-10-30 00:45:03.137019 | NULL          |
|      36 | test36    | [email protected] | 12670    | 2018-10-30 00:45:03.137753 | NULL          |
|      39 | test39    | [email protected] | 848919   | 2018-10-30 00:45:03.139071 | NULL          |
|      42 | test42    | [email protected] | 571448   | 2018-10-30 00:45:03.139800 | NULL          |
|      45 | test45    | [email protected] | 795033   | 2018-10-30 00:45:03.140792 | NULL          |
|      48 | test48    | [email protected] | 173555   | 2018-10-30 00:45:03.142139 | NULL          |
|      51 | test51    | [email protected] | 418536   | 2018-10-30 00:45:03.143215 | NULL          |
|      54 | test54    | [email protected] | 796930   | 2018-10-30 00:45:03.144229 | NULL          |
|      57 | test57    | [email protected] | 453970   | 2018-10-30 00:45:03.145270 | NULL          |
|      60 | test60    | [email protected] | 800511   | 2018-10-30 00:45:03.146273 | NULL          |
|      63 | test63    | [email protected] | 783696   | 2018-10-30 00:45:03.147218 | NULL          |
|      66 | test66    | [email protected] | 81956    | 2018-10-30 00:45:03.148277 | NULL          |
|      69 | test69    | [email protected] | 396697   | 2018-10-30 00:45:03.149708 | NULL          |
|      72 | test72    | [email protected] | 522975   | 2018-10-30 00:45:03.151594 | NULL          |
|      75 | test75    | [email protected] | 127242   | 2018-10-30 00:45:03.153122 | NULL          |
|      78 | test78    | [email protected] | 59026    | 2018-10-30 00:45:03.154210 | NULL          |
|      81 | test81    | [email protected] | 286569   | 2018-10-30 00:45:03.155240 | NULL          |
|      84 | test84    | [email protected] | 331839   | 2018-10-30 00:45:03.156243 | NULL          |
|      87 | test87    | [email protected] | 809766   | 2018-10-30 00:45:03.157165 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
30 rows in set (0.114 sec)

MariaDB [testdb0]> 
MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 0,5;  -- 第1页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|       0 | test0     | [email protected]  | 723968   | 2018-10-30 00:45:03.120618 | NULL          |
|       3 | test3     | [email protected]  | 623938   | 2018-10-30 00:45:03.123731 | NULL          |
|       6 | test6     | [email protected]  | 367932   | 2018-10-30 00:45:03.125267 | NULL          |
|       9 | test9     | [email protected]  | 588289   | 2018-10-30 00:45:03.126534 | NULL          |
|      12 | test12    | [email protected] | 129007   | 2018-10-30 00:45:03.127923 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.115 sec)

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;  -- 第2页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      15 | test15    | [email protected] | 436787   | 2018-10-30 00:45:03.130163 | NULL          |
|      18 | test18    | [email protected] | 459812   | 2018-10-30 00:45:03.131413 | NULL          |
|      21 | test21    | [email protected] | 991766   | 2018-10-30 00:45:03.132423 | NULL          |
|      24 | test24    | [email protected] | 926347   | 2018-10-30 00:45:03.133656 | NULL          |
|      27 | test27    | [email protected] | 330094   | 2018-10-30 00:45:03.134957 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.120 sec)

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 10,5;  -- 第3页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      30 | test30    | [email protected] | 396205   | 2018-10-30 00:45:03.135756 | NULL          |
|      33 | test33    | [email protected] | 783877   | 2018-10-30 00:45:03.137019 | NULL          |
|      36 | test36    | [email protected] | 12670    | 2018-10-30 00:45:03.137753 | NULL          |
|      39 | test39    | [email protected] | 848919   | 2018-10-30 00:45:03.139071 | NULL          |
|      42 | test42    | [email protected] | 571448   | 2018-10-30 00:45:03.139800 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.121 sec)

MariaDB [testdb0]> 

第2个数据库节点

$ mysql -uroot -h192.168.10.11 -p123456
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 26
Server version: 10.3.10-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use testdb1
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 0,30;  -- 第1页,每页30行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|       1 | test1     | [email protected]  | 749248   | 2018-10-30 00:45:03.122768 | NULL          |
|       4 | test4     | [email protected]  | 396682   | 2018-10-30 00:45:03.124253 | NULL          |
|       7 | test7     | [email protected]  | 504876   | 2018-10-30 00:45:03.125680 | NULL          |
|      10 | test10    | [email protected] | 679698   | 2018-10-30 00:45:03.127149 | NULL          |
|      13 | test13    | [email protected] | 744177   | 2018-10-30 00:45:03.128836 | NULL          |
|      16 | test16    | [email protected] | 182346   | 2018-10-30 00:45:03.130450 | NULL          |
|      19 | test19    | [email protected] | 494952   | 2018-10-30 00:45:03.131681 | NULL          |
|      22 | test22    | [email protected] | 672856   | 2018-10-30 00:45:03.132717 | NULL          |
|      25 | test25    | [email protected] | 464786   | 2018-10-30 00:45:03.133945 | NULL          |
|      28 | test28    | [email protected] | 15801    | 2018-10-30 00:45:03.135256 | NULL          |
|      31 | test31    | [email protected] | 714861   | 2018-10-30 00:45:03.136280 | NULL          |
|      34 | test34    | [email protected] | 762310   | 2018-10-30 00:45:03.137254 | NULL          |
|      37 | test37    | [email protected] | 683589   | 2018-10-30 00:45:03.138255 | NULL          |
|      40 | test40    | [email protected] | 104783   | 2018-10-30 00:45:03.139306 | NULL          |
|      43 | test43    | [email protected] | 925761   | 2018-10-30 00:45:03.140221 | NULL          |
|      46 | test46    | [email protected] | 231775   | 2018-10-30 00:45:03.141379 | NULL          |
|      49 | test49    | [email protected] | 546448   | 2018-10-30 00:45:03.142399 | NULL          |
|      52 | test52    | [email protected] | 457953   | 2018-10-30 00:45:03.143479 | NULL          |
|      55 | test55    | [email protected] | 882178   | 2018-10-30 00:45:03.144484 | NULL          |
|      58 | test58    | [email protected] | 209548   | 2018-10-30 00:45:03.145568 | NULL          |
|      61 | test61    | [email protected] | 945062   | 2018-10-30 00:45:03.146522 | NULL          |
|      64 | test64    | [email protected] | 947155   | 2018-10-30 00:45:03.147487 | NULL          |
|      67 | test67    | [email protected] | 255729   | 2018-10-30 00:45:03.148598 | NULL          |
|      70 | test70    | [email protected] | 885156   | 2018-10-30 00:45:03.150226 | NULL          |
|      73 | test73    | [email protected] | 907812   | 2018-10-30 00:45:03.152236 | NULL          |
|      76 | test76    | [email protected] | 725802   | 2018-10-30 00:45:03.153404 | NULL          |
|      79 | test79    | [email protected] | 553271   | 2018-10-30 00:45:03.154481 | NULL          |
|      82 | test82    | [email protected] | 665017   | 2018-10-30 00:45:03.155528 | NULL          |
|      85 | test85    | [email protected] | 263061   | 2018-10-30 00:45:03.156504 | NULL          |
|      88 | test88    | [email protected] | 89461    | 2018-10-30 00:45:03.157420 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
30 rows in set (0.118 sec)

MariaDB [testdb1]>
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 0,5;  -- 第1页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|       1 | test1     | [email protected]  | 749248   | 2018-10-30 00:45:03.122768 | NULL          |
|       4 | test4     | [email protected]  | 396682   | 2018-10-30 00:45:03.124253 | NULL          |
|       7 | test7     | [email protected]  | 504876   | 2018-10-30 00:45:03.125680 | NULL          |
|      10 | test10    | [email protected] | 679698   | 2018-10-30 00:45:03.127149 | NULL          |
|      13 | test13    | [email protected] | 744177   | 2018-10-30 00:45:03.128836 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.117 sec)

MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;  -- 第2页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      16 | test16    | [email protected] | 182346   | 2018-10-30 00:45:03.130450 | NULL          |
|      19 | test19    | [email protected] | 494952   | 2018-10-30 00:45:03.131681 | NULL          |
|      22 | test22    | [email protected] | 672856   | 2018-10-30 00:45:03.132717 | NULL          |
|      25 | test25    | [email protected] | 464786   | 2018-10-30 00:45:03.133945 | NULL          |
|      28 | test28    | [email protected] | 15801    | 2018-10-30 00:45:03.135256 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.117 sec)

MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 10,5;  -- 第3页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      31 | test31    | [email protected] | 714861   | 2018-10-30 00:45:03.136280 | NULL          |
|      34 | test34    | [email protected] | 762310   | 2018-10-30 00:45:03.137254 | NULL          |
|      37 | test37    | [email protected] | 683589   | 2018-10-30 00:45:03.138255 | NULL          |
|      40 | test40    | [email protected] | 104783   | 2018-10-30 00:45:03.139306 | NULL          |
|      43 | test43    | [email protected] | 925761   | 2018-10-30 00:45:03.140221 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.119 sec)

MariaDB [testdb1]> 

第3个数据库节点

 

$ mysql -uroot -h192.168.10.12 -p123456
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 27
Server version: 10.3.10-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use testdb2
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 0,30;  -- 第1页,每页30行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|       2 | test2     | [email protected]  | 574336   | 2018-10-30 00:45:03.123408 | NULL          |
|       5 | test5     | [email protected]  | 111595   | 2018-10-30 00:45:03.124665 | NULL          |
|       8 | test8     | [email protected]  | 420583   | 2018-10-30 00:45:03.126236 | NULL          |
|      11 | test11    | [email protected] | 633620   | 2018-10-30 00:45:03.127411 | NULL          |
|      14 | test14    | [email protected] | 333863   | 2018-10-30 00:45:03.129391 | NULL          |
|      17 | test17    | [email protected] | 601370   | 2018-10-30 00:45:03.130819 | NULL          |
|      20 | test20    | [email protected] | 95324    | 2018-10-30 00:45:03.132136 | NULL          |
|      23 | test23    | [email protected] | 388983   | 2018-10-30 00:45:03.133231 | NULL          |
|      26 | test26    | [email protected] | 544890   | 2018-10-30 00:45:03.134524 | NULL          |
|      29 | test29    | [email protected] | 88721    | 2018-10-30 00:45:03.135494 | NULL          |
|      32 | test32    | [email protected] | 385692   | 2018-10-30 00:45:03.136537 | NULL          |
|      35 | test35    | [email protected] | 459920   | 2018-10-30 00:45:03.137486 | NULL          |
|      38 | test38    | [email protected] | 379937   | 2018-10-30 00:45:03.138554 | NULL          |
|      41 | test41    | [email protected] | 977159   | 2018-10-30 00:45:03.139536 | NULL          |
|      44 | test44    | [email protected] | 914463   | 2018-10-30 00:45:03.140512 | NULL          |
|      47 | test47    | [email protected] | 773776   | 2018-10-30 00:45:03.141648 | NULL          |
|      50 | test50    | [email protected] | 211576   | 2018-10-30 00:45:03.142665 | NULL          |
|      53 | test53    | [email protected] | 34158    | 2018-10-30 00:45:03.143774 | NULL          |
|      56 | test56    | [email protected] | 20101    | 2018-10-30 00:45:03.144770 | NULL          |
|      59 | test59    | [email protected] | 685831   | 2018-10-30 00:45:03.146028 | NULL          |
|      62 | test62    | [email protected] | 323776   | 2018-10-30 00:45:03.146824 | NULL          |
|      65 | test65    | [email protected] | 384684   | 2018-10-30 00:45:03.147819 | NULL          |
|      68 | test68    | [email protected] | 32777    | 2018-10-30 00:45:03.149365 | NULL          |
|      71 | test71    | [email protected] | 235688   | 2018-10-30 00:45:03.150772 | NULL          |
|      74 | test74    | [email protected] | 970136   | 2018-10-30 00:45:03.152536 | NULL          |
|      77 | test77    | [email protected] | 247286   | 2018-10-30 00:45:03.153726 | NULL          |
|      80 | test80    | [email protected] | 589276   | 2018-10-30 00:45:03.154719 | NULL          |
|      83 | test83    | [email protected] | 465378   | 2018-10-30 00:45:03.155809 | NULL          |
|      86 | test86    | [email protected] | 319790   | 2018-10-30 00:45:03.156748 | NULL          |
|      89 | test89    | [email protected] | 18006    | 2018-10-30 00:45:03.157663 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
30 rows in set (0.114 sec)

MariaDB [testdb2]>
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 0,5;  -- 第1页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|       2 | test2     | [email protected]  | 574336   | 2018-10-30 00:45:03.123408 | NULL          |
|       5 | test5     | [email protected]  | 111595   | 2018-10-30 00:45:03.124665 | NULL          |
|       8 | test8     | [email protected]  | 420583   | 2018-10-30 00:45:03.126236 | NULL          |
|      11 | test11    | [email protected] | 633620   | 2018-10-30 00:45:03.127411 | NULL          |
|      14 | test14    | [email protected] | 333863   | 2018-10-30 00:45:03.129391 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.115 sec)

MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;  -- 第2页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      17 | test17    | [email protected] | 601370   | 2018-10-30 00:45:03.130819 | NULL          |
|      20 | test20    | [email protected] | 95324    | 2018-10-30 00:45:03.132136 | NULL          |
|      23 | test23    | [email protected] | 388983   | 2018-10-30 00:45:03.133231 | NULL          |
|      26 | test26    | [email protected] | 544890   | 2018-10-30 00:45:03.134524 | NULL          |
|      29 | test29    | [email protected] | 88721    | 2018-10-30 00:45:03.135494 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.115 sec)

MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 10,5;  -- 第3页,每页5行
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      32 | test32    | [email protected] | 385692   | 2018-10-30 00:45:03.136537 | NULL          |
|      35 | test35    | [email protected] | 459920   | 2018-10-30 00:45:03.137486 | NULL          |
|      38 | test38    | [email protected] | 379937   | 2018-10-30 00:45:03.138554 | NULL          |
|      41 | test41    | [email protected] | 977159   | 2018-10-30 00:45:03.139536 | NULL          |
|      44 | test44    | [email protected] | 914463   | 2018-10-30 00:45:03.140512 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.116 sec)

MariaDB [testdb2]> 

正式进入主题  采用高效精确的二次查询方案

假如网页上每翻页一次,只显示15条记录

例如显示第2页记录 来自3个数据库节点

SELECT * FROM users ORDER BY created_at LIMIT 页码值  * (显示15条/3个数据库节点数),(显示15条/3个数据库节点数)

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 5,5; -- 第2页显示网页中15条记录中的部分记录
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      15 | test15    | [email protected] | 436787   | 2018-10-30 00:45:03.130163 | NULL          |
|      18 | test18    | [email protected] | 459812   | 2018-10-30 00:45:03.131413 | NULL          |
|      21 | test21    | [email protected] | 991766   | 2018-10-30 00:45:03.132423 | NULL          |
|      24 | test24    | [email protected] | 926347   | 2018-10-30 00:45:03.133656 | NULL          |
|      27 | test27    | [email protected] | 330094   | 2018-10-30 00:45:03.134957 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.125 sec)
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;  -- 第2页显示网页中15条记录中的部分记录
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      16 | test16    | [email protected] | 182346   | 2018-10-30 00:45:03.130450 | NULL          |
|      19 | test19    | [email protected] | 494952   | 2018-10-30 00:45:03.131681 | NULL          |
|      22 | test22    | [email protected] | 672856   | 2018-10-30 00:45:03.132717 | NULL          |
|      25 | test25    | [email protected] | 464786   | 2018-10-30 00:45:03.133945 | NULL          |
|      28 | test28    | [email protected] | 15801    | 2018-10-30 00:45:03.135256 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.129 sec)
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;  -- 第2页显示网页中15条记录中的部分记录
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      17 | test17    | [email protected] | 601370   | 2018-10-30 00:45:03.130819 | NULL          |
|      20 | test20    | [email protected] | 95324    | 2018-10-30 00:45:03.132136 | NULL          |
|      23 | test23    | [email protected] | 388983   | 2018-10-30 00:45:03.133231 | NULL          |
|      26 | test26    | [email protected] | 544890   | 2018-10-30 00:45:03.134524 | NULL          |
|      29 | test29    | [email protected] | 88721    | 2018-10-30 00:45:03.135494 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.127 sec)

MariaDB [testdb2]>

将上面3个结果合并在一起再次排序一次(我们可以用PHP Python Golang Java C# 等等语言实现此需求)

获得如下结果显示到页面上:

第1页 user_id 值范围从0开始到14结束,第2页 user_id 值范围从15开始到29结束

+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      15 | test15    | [email protected] | 436787   | 2018-10-30 00:45:03.130163 | NULL          |
|      16 | test16    | [email protected] | 182346   | 2018-10-30 00:45:03.130450 | NULL          |
|      17 | test17    | [email protected] | 601370   | 2018-10-30 00:45:03.130819 | NULL          |
|      18 | test18    | [email protected] | 459812   | 2018-10-30 00:45:03.131413 | NULL          |
|      19 | test19    | [email protected] | 494952   | 2018-10-30 00:45:03.131681 | NULL          |
|      20 | test20    | [email protected] | 95324    | 2018-10-30 00:45:03.132136 | NULL          |
|      21 | test21    | [email protected] | 991766   | 2018-10-30 00:45:03.132423 | NULL          |
|      22 | test22    | [email protected] | 672856   | 2018-10-30 00:45:03.132717 | NULL          |
|      23 | test23    | [email protected] | 388983   | 2018-10-30 00:45:03.133231 | NULL          |
|      24 | test24    | [email protected] | 926347   | 2018-10-30 00:45:03.133656 | NULL          |
|      25 | test25    | [email protected] | 464786   | 2018-10-30 00:45:03.133945 | NULL          |
|      26 | test26    | [email protected] | 544890   | 2018-10-30 00:45:03.134524 | NULL          |
|      27 | test27    | [email protected] | 330094   | 2018-10-30 00:45:03.134957 | NULL          |
|      28 | test28    | [email protected] | 15801    | 2018-10-30 00:45:03.135256 | NULL          |
|      29 | test29    | [email protected] | 88721    | 2018-10-30 00:45:03.135494 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+

假如第3个数据库节点testdb2,user_id >= 26 的主键都不存在,模拟节点数据分布不均匀的情形

MariaDB [testdb2]> DELETE FROM users WHERE user_id >= 26;
Query OK, 333325 rows affected (1.343 sec)

MariaDB [testdb2]> 

继续补充说明,把user_id >= 26 的主键都删掉,意思是第2页第3个数据库节点testdb2只会返回3条记录

我们一共需要15条记录,但是只返回13条记录从3个数据库节点,这显然是不对的,因为我们的数据库全部节点里面可有几十万行记录啊

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      15 | test15    | [email protected] | 436787   | 2018-10-30 00:45:03.130163 | NULL          |
|      18 | test18    | [email protected] | 459812   | 2018-10-30 00:45:03.131413 | NULL          |
|      21 | test21    | [email protected] | 991766   | 2018-10-30 00:45:03.132423 | NULL          |
|      24 | test24    | [email protected] | 926347   | 2018-10-30 00:45:03.133656 | NULL          |
|      27 | test27    | [email protected] | 330094   | 2018-10-30 00:45:03.134957 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.361 sec)

MariaDB [testdb0]> 
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      16 | test16    | [email protected] | 182346   | 2018-10-30 00:45:03.130450 | NULL          |
|      19 | test19    | [email protected] | 494952   | 2018-10-30 00:45:03.131681 | NULL          |
|      22 | test22    | [email protected] | 672856   | 2018-10-30 00:45:03.132717 | NULL          |
|      25 | test25    | [email protected] | 464786   | 2018-10-30 00:45:03.133945 | NULL          |
|      28 | test28    | [email protected] | 15801    | 2018-10-30 00:45:03.135256 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.557 sec)

MariaDB [testdb1]> 
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 5,5;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      17 | test17    | [email protected] | 601370   | 2018-10-30 00:45:03.130819 | NULL          |
|      20 | test20    | [email protected] | 95324    | 2018-10-30 00:45:03.132136 | NULL          |
|      23 | test23    | [email protected] | 388983   | 2018-10-30 00:45:03.133231 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
3 rows in set (0.001 sec)

MariaDB [testdb2]> 

缺少2条记录,此时不知道这2条记录该来自哪些节点,那么一次性搞定的办法就是第2次查询时,每页每个节点返回7条记录

遵循以下动态规则

SELECT * FROM users ORDER BY created_at LIMIT 页码值  * (显示15条/3个数据库节点数),(显示15条/3个数据库节点数+缺少的记录行数)

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 5,7;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      15 | test15    | [email protected] | 436787   | 2018-10-30 00:45:03.130163 | NULL          |
|      18 | test18    | [email protected] | 459812   | 2018-10-30 00:45:03.131413 | NULL          |
|      21 | test21    | [email protected] | 991766   | 2018-10-30 00:45:03.132423 | NULL          |
|      24 | test24    | [email protected] | 926347   | 2018-10-30 00:45:03.133656 | NULL          |
|      27 | test27    | [email protected] | 330094   | 2018-10-30 00:45:03.134957 | NULL          |
|      30 | test30    | [email protected] | 396205   | 2018-10-30 00:45:03.135756 | NULL          |
|      33 | test33    | [email protected] | 783877   | 2018-10-30 00:45:03.137019 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
7 rows in set (0.131 sec)

MariaDB [testdb0]> 
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 5,7;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      16 | test16    | [email protected] | 182346   | 2018-10-30 00:45:03.130450 | NULL          |
|      19 | test19    | [email protected] | 494952   | 2018-10-30 00:45:03.131681 | NULL          |
|      22 | test22    | [email protected] | 672856   | 2018-10-30 00:45:03.132717 | NULL          |
|      25 | test25    | [email protected] | 464786   | 2018-10-30 00:45:03.133945 | NULL          |
|      28 | test28    | [email protected] | 15801    | 2018-10-30 00:45:03.135256 | NULL          |
|      31 | test31    | [email protected] | 714861   | 2018-10-30 00:45:03.136280 | NULL          |
|      34 | test34    | [email protected] | 762310   | 2018-10-30 00:45:03.137254 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
7 rows in set (0.118 sec)

MariaDB [testdb1]> 
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 5,7;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      17 | test17    | [email protected] | 601370   | 2018-10-30 00:45:03.130819 | NULL          |
|      20 | test20    | [email protected] | 95324    | 2018-10-30 00:45:03.132136 | NULL          |
|      23 | test23    | [email protected] | 388983   | 2018-10-30 00:45:03.133231 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
3 rows in set (0.001 sec)

MariaDB [testdb2]> 

将合并的结果排序后,只取前15条记录,丢弃最后2条,这样第2页显示15条记录就齐活啦

那么第3页翻页时显示时,该发送怎样SQL到每个数据库节点呢?

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 10,5;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      30 | test30    | [email protected] | 396205   | 2018-10-30 00:45:03.135756 | NULL          |
|      33 | test33    | [email protected] | 783877   | 2018-10-30 00:45:03.137019 | NULL          |
|      36 | test36    | [email protected] | 12670    | 2018-10-30 00:45:03.137753 | NULL          |
|      39 | test39    | [email protected] | 848919   | 2018-10-30 00:45:03.139071 | NULL          |
|      42 | test42    | [email protected] | 571448   | 2018-10-30 00:45:03.139800 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.120 sec)

MariaDB [testdb0]> 
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 10,5;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      31 | test31    | [email protected] | 714861   | 2018-10-30 00:45:03.136280 | NULL          |
|      34 | test34    | [email protected] | 762310   | 2018-10-30 00:45:03.137254 | NULL          |
|      37 | test37    | [email protected] | 683589   | 2018-10-30 00:45:03.138255 | NULL          |
|      40 | test40    | [email protected] | 104783   | 2018-10-30 00:45:03.139306 | NULL          |
|      43 | test43    | [email protected] | 925761   | 2018-10-30 00:45:03.140221 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
5 rows in set (0.118 sec)

MariaDB [testdb1]> 
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 10,5;
Empty set (0.001 sec)

MariaDB [testdb2]>

后面所有的翻页规则依然遵循以下动态规则,此时缺少5行记录

SELECT * FROM users ORDER BY created_at LIMIT 页码值  * (显示15条/3个数据库节点数),(显示15条/3个数据库节点数+缺少的记录行数)

MariaDB [testdb0]> SELECT * FROM users ORDER BY created_at LIMIT 10,10;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      30 | test30    | [email protected] | 396205   | 2018-10-30 00:45:03.135756 | NULL          |
|      33 | test33    | [email protected] | 783877   | 2018-10-30 00:45:03.137019 | NULL          |
|      36 | test36    | [email protected] | 12670    | 2018-10-30 00:45:03.137753 | NULL          |
|      39 | test39    | [email protected] | 848919   | 2018-10-30 00:45:03.139071 | NULL          |
|      42 | test42    | [email protected] | 571448   | 2018-10-30 00:45:03.139800 | NULL          |
|      45 | test45    | [email protected] | 795033   | 2018-10-30 00:45:03.140792 | NULL          |
|      48 | test48    | [email protected] | 173555   | 2018-10-30 00:45:03.142139 | NULL          |
|      51 | test51    | [email protected] | 418536   | 2018-10-30 00:45:03.143215 | NULL          |
|      54 | test54    | [email protected] | 796930   | 2018-10-30 00:45:03.144229 | NULL          |
|      57 | test57    | [email protected] | 453970   | 2018-10-30 00:45:03.145270 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
10 rows in set (0.117 sec)

MariaDB [testdb0]> 
MariaDB [testdb1]> SELECT * FROM users ORDER BY created_at LIMIT 10,10;
+---------+-----------+----------------+----------+----------------------------+---------------+
| user_id | user_name | email          | password | created_at                 | last_modified |
+---------+-----------+----------------+----------+----------------------------+---------------+
|      31 | test31    | [email protected] | 714861   | 2018-10-30 00:45:03.136280 | NULL          |
|      34 | test34    | [email protected] | 762310   | 2018-10-30 00:45:03.137254 | NULL          |
|      37 | test37    | [email protected] | 683589   | 2018-10-30 00:45:03.138255 | NULL          |
|      40 | test40    | [email protected] | 104783   | 2018-10-30 00:45:03.139306 | NULL          |
|      43 | test43    | [email protected] | 925761   | 2018-10-30 00:45:03.140221 | NULL          |
|      46 | test46    | [email protected] | 231775   | 2018-10-30 00:45:03.141379 | NULL          |
|      49 | test49    | [email protected] | 546448   | 2018-10-30 00:45:03.142399 | NULL          |
|      52 | test52    | [email protected] | 457953   | 2018-10-30 00:45:03.143479 | NULL          |
|      55 | test55    | [email protected] | 882178   | 2018-10-30 00:45:03.144484 | NULL          |
|      58 | test58    | [email protected] | 209548   | 2018-10-30 00:45:03.145568 | NULL          |
+---------+-----------+----------------+----------+----------------------------+---------------+
10 rows in set (0.120 sec)

MariaDB [testdb1]> 
MariaDB [testdb2]> SELECT * FROM users ORDER BY created_at LIMIT 10,10;
Empty set (0.000 sec)

MariaDB [testdb2]>

合并排序后,只取前15条记录,丢弃最后5条记录,在第2页中丢弃的user_id=42,user_id=43这两行记录此时出现在第3页网页上

二次查询虽然查询了两次,但是返回的记录精准,因为每个节点获取的数据量很少,性能非常优秀

不管数据源是采用何种哈希算法来切分存储数据,此方案通杀通用!

你可能感兴趣的:(MySQL)