【问题标题】:Paginating results from union of two tables两个表联合的分页结果
【发布时间】:2019-09-11 10:27:26
【问题描述】:

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

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

这样,服务器从两个表中选择所有记录,按日期排序,然后应用分页。

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

【问题讨论】:

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


    【解决方案1】:

    有一种技术叫做Seek Method,你可以阅读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

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

    我希望这会有所帮助。

    【讨论】:

    • 感谢您的回答,但排序是基于日期和时间的,并且有两个表,这对我也没有多大帮助。例如,如果我索引它们,它可以是 z1 r1 r2 r3 z2 r4 r5 r6 r7 r8 z3 等,我需要两个标记。
    猜你喜欢
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 2019-09-07
    • 1970-01-01
    相关资源
    最近更新 更多