两个表的并集的分页结果

时间:2019-04-22 07:36:16

标签: mysql pagination sql-order-by union-all

我在对两个大表进行分页时遇到问题:

Receipts table: id, receipt_date, record_details (650k records)
Z Reports table: id, receipt_date, record_details (88k records)

我想要做的是用receipt_date和union对这两个表进行排序,然后再对它们进行分页。目前,我有此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

通过这种方式,服务器从两个表中选择所有记录,并按日期对它们进行排序,然后应用分页。

但是,当行数增加时,此查询将需要更长的时间才能完成。是否有其他算法可以得到相同的结果而不依赖于表的大小?

1 个答案:

答案 0 :(得分:0)

有一种称为“寻找方法”的技术,您可以阅读有关here的信息。据此,您需要标识一组唯一标识每一行的列。在数据库中搜索时,这组列将与谓词一起使用。

我提到的链接有一些示例,但这是另一个示例,一个非常简单的示例:

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;

SQLFiddle Link

具有索引将进一步加快分页速度。

我希望这会有所帮助。