mysql - 两个表联合的分页结果
问题描述
我在对两个大表进行分页时遇到问题:
Receipts table: id, receipt_date, record_details (650k records)
Z Reports table: id, receipt_date, record_details (88k records)
我想要做的是通过receipt_date
和联合对这两个表进行排序,然后我想对它们进行分页。目前我有这个 SQL(不完全是,但主要思想是这个):
SELECT c.id, c.receipt_date, c.col_type FROM (
SELECT a.id, a.receipt_date, 'receipt' AS coltype
FROM `terminal_receipts` a
WHERE `a`.`deleted` IS NULL
UNION ALL
SELECT b.id, b.receipt_date, 'zreport' AS coltype
FROM z_reports` b WHERE `b`.`deleted` IS NULL
) c
ORDER BY receipt_date desc LIMIT 50 OFFSET 0
这样,服务器从两个表中选择所有记录,按日期对它们进行排序,然后应用分页。
但是当行数增加时,此查询将需要更长的时间才能完成。是否有任何其他算法可以在不依赖表大小的情况下获得相同的结果?
解决方案
有一种叫做 Seek Method 的技术,你可以在这里阅读。根据它,您需要识别一组唯一标识每一行的列。然后,在搜索数据库时,这组列将与谓词一起使用。
我提到的链接有一些例子,但这里有另一个例子,一个非常简单的例子:
CREATE TABLE IF NOT EXISTS `docs` (
`id` int(6) unsigned NOT NULL,
`rev` int(3) unsigned NOT NULL,
`content` varchar(200) NOT NULL,
PRIMARY KEY (`id`,`rev`)
) DEFAULT CHARSET=utf8;
INSERT INTO `docs` (`id`, `rev`, `content`) VALUES
('1', '1', 'The earth is flat'),
('2', '1', 'One hundred angels can dance on the head of a pin'),
('1', '2', 'The earth is flat and rests on a bull\'s horn'),
('1', '3', 'The earth is like a ball.');
SELECT *
FROM `docs`
ORDER BY rev, id
LIMIT 2;
SELECT *
FROM `docs`
WHERE (rev, id) > (1, 2) # let's use the last row from the previous select with the predicate
ORDER BY rev, id
LIMIT 2;
SELECT *
FROM `docs`
WHERE (rev, id) > (3, 1) # same idea
ORDER BY rev, id
LIMIT 2;
拥有索引将进一步加快分页速度。
我希望这有帮助。
推荐阅读
- scripting - 在 tcl 中重定向 exec 命令输出
- html - 如何使用文件夹中的本地视频而不是 Youtube URL?
- python - Django ORM 最快查询连接两个模型并获取配对元组列表
- r - 无法替换R中的空格
- javascript - d3.js 根据 id 选择
- regex - 使用 VBA RegEx 查找格式范围并保持速度
- python - ModuleNotFoundError:没有名为“tensorflow.contrib”的模块;'tensorflow' 不是一个包
- haskell - 使用封闭类型族编写函数“如果类型 A,则类型 X,否则类型 Y”
- python - 使用 Pyinstaller 转换后如何记住 Tkinter Entry 中的输入历史记录?
- r - 通过 ggplot2 抑制小提琴图中的分散抖动点