Php 对不同来源的项目进行分页
我面临一个问题:我需要列出一些项目。这些项目来自不同的来源(比如表A、表B、表C),具有不同的属性和性质(尽管有些是常见的) 如何将它们合并到已分页的列表中 我考虑过的选择是:Php 对不同来源的项目进行分页,php,mysql,sql,pagination,mariadb,Php,Mysql,Sql,Pagination,Mariadb,我面临一个问题:我需要列出一些项目。这些项目来自不同的来源(比如表A、表B、表C),具有不同的属性和性质(尽管有些是常见的) 如何将它们合并到已分页的列表中 我考虑过的选择是: 首先获取它们,然后在代码中对它们进行排序和分页。这样做效果不好,因为项目太多(数千个),性能混乱 在SQL视图中将它们与它们的共享属性连接起来,SQL查询完成后,只重新加载分页的项以获取它们的其余属性。到目前为止,这是可行的,但如果来源发生变化/增加,则可能难以维护 你知道还有别的选择吗?基本上,对来自两个数据源(S
- 首先获取它们,然后在代码中对它们进行排序和分页。这样做效果不好,因为项目太多(数千个),性能混乱
- 在SQL视图中将它们与它们的共享属性连接起来,SQL查询完成后,只重新加载分页的项以获取它们的其余属性。到目前为止,这是可行的,但如果来源发生变化/增加,则可能难以维护
谢谢。事实上,我最近不得不回答一个类似的问题,特别是在两个大表之间进行报告,并在这两个表之间进行分页。我得到的答案是使用子查询,如下所示:
SELECT
t1.id as 't1_id',
t1.name as 't1_name',
t1.attribute as 't1_attribute',
t2.id as 't2_id',
t2.name as 't2_name',
t2.attribute as 't2_attribute',
l.attribute as 'l_attribute'
FROM (
SELECT
id, name, attribute
FROM
table1
/* You can perform joins in here if you want, just make sure you're using your aliases right */
/* You can also put where statements here */
ORDER BY
name DESC, id ASC
LIMIT 0,50
) as t1
INNER JOIN (
SELECT
id,
name,
attribute
FROM
table2
ORDER BY
attribute ASC
LIMIT 250,50
) as t2
ON t2.id IS NOT NULL
LEFT JOIN
linkingTable as l
ON l.t1Id = t1.id
AND l.t2Id = t2.id
/* Do your wheres and stuff here */
/* You shouldn't need to do any additional ordering or limiting */
事实上,我最近不得不回答一个类似的情况,特别是在两个大表之间报告,并在这两个表之间分页。我得到的答案是使用子查询,如下所示:
SELECT
t1.id as 't1_id',
t1.name as 't1_name',
t1.attribute as 't1_attribute',
t2.id as 't2_id',
t2.name as 't2_name',
t2.attribute as 't2_attribute',
l.attribute as 'l_attribute'
FROM (
SELECT
id, name, attribute
FROM
table1
/* You can perform joins in here if you want, just make sure you're using your aliases right */
/* You can also put where statements here */
ORDER BY
name DESC, id ASC
LIMIT 0,50
) as t1
INNER JOIN (
SELECT
id,
name,
attribute
FROM
table2
ORDER BY
attribute ASC
LIMIT 250,50
) as t2
ON t2.id IS NOT NULL
LEFT JOIN
linkingTable as l
ON l.t1Id = t1.id
AND l.t2Id = t2.id
/* Do your wheres and stuff here */
/* You shouldn't need to do any additional ordering or limiting */
如果
UNION
解决了这个问题,下面是一些语法和优化技巧
这将提供第21页,共10行页面:
(
( SELECT ... LIMIT 210 )
UNION [ALL|DISTINCT]
( SELECT ... LIMIT 210 )
) ORDER BY ... LIMIT 10 OFFSET 200
注意210=200+10。您不能信任在内部选择中使用偏移量
使用UNION ALL
表示速度,但如果选项之间可能存在重复行
,则明确地说UNION DISTINCT
如果去掉太多的括号,将得到语法错误或“错误”结果
如果以子查询结束,请重复ORDER BY
,但不要重复LIMIT
:
SELECT ...
FROM (
( SELECT ... LIMIT 210 )
UNION [ALL|DISTINCT]
( SELECT ... LIMIT 210 )
ORDER BY ... LIMIT 10 OFFSET 200
) AS u
JOIN something_else ON ...
ORDER BY ...
可能包含连接的一个原因是为了性能——子查询u
将结果集缩减到只有10行,因此连接只需要查找10个内容。将连接
放在内部会导致大量的连接,然后再缩减到10个。如果联合
解决了这个问题,下面是一些语法和优化技巧
这将提供第21页,共10行页面:
(
( SELECT ... LIMIT 210 )
UNION [ALL|DISTINCT]
( SELECT ... LIMIT 210 )
) ORDER BY ... LIMIT 10 OFFSET 200
注意210=200+10。您不能信任在内部选择中使用偏移量
使用UNION ALL
表示速度,但如果选项之间可能存在重复行
,则明确地说UNION DISTINCT
如果去掉太多的括号,将得到语法错误或“错误”结果
如果以子查询结束,请重复ORDER BY
,但不要重复LIMIT
:
SELECT ...
FROM (
( SELECT ... LIMIT 210 )
UNION [ALL|DISTINCT]
( SELECT ... LIMIT 210 )
ORDER BY ... LIMIT 10 OFFSET 200
) AS u
JOIN something_else ON ...
ORDER BY ...
可能包含连接的一个原因是为了性能——子查询u
将结果集缩减到只有10行,因此连接只需要查找10个内容。将JOIN
放入内部将导致大量的加入,然后将其缩减为10个。也许Union
会有所帮助:@MadhurBhaiya这就是我创建SQL视图所做的。:)我认为你的问题是公平的。视图将工作,但是如果行数增长很多,则需要考虑性能问题。您可能需要添加索引以加快速度,或者可能需要使用物化视图(FlexView)。您主要关心什么?速度、数据库资源消耗、可维护性、调试?@用户的更快响应时间和开发人员的可维护性是我主要关心的问题。我来看看物化视图,谢谢!也许Union
能帮上忙:@MadhurBhaiya这就是我创建SQL视图的目的:我认为你的问题是公平的。视图将工作,但是如果行数增长很多,则需要考虑性能问题。您可能需要添加索引以加快速度,或者可能需要使用物化视图(FlexView)。您主要关心什么?速度、数据库资源消耗、可维护性、调试?@用户的更快响应时间和开发人员的可维护性是我主要关心的问题。我来看看物化视图,谢谢!还需要注意的是,有一些方法可以确保编译结果集的顺序将一个表优先于另一个可伸缩性相当好的表。我没有包括它们,因为我不确定它是否在您想要做的范围内,但如果您需要它们,请发表评论,我将编辑以包括它们。另外,还有一些方法可以确保编译结果集的顺序将一个表优先于另一个表,并且可以很好地扩展。我没有包括它们,因为我不确定它是否在您想要做的范围内,但是如果您需要它们,请发表评论,我会编辑以包括它们。在您的评论中,您说不要担心视图等。是因为我不需要它,还是我不应该这样做,因为这会使性能更差?我说的是大约5000排,很快就会达到100000排,但我怀疑它是否会超过这个数字。提前感谢。@Jachinair-A视图
主要是底层选择
的语法糖;如果你愿意的话,可以看一看。要形成一个物化的视图需要你自己的努力;它在MySQL中不是自动化的;在这种情况下,这似乎不合适。在你的评论中,你说不要担心视图,等等。是因为我不需要它,还是我不应该这样做,因为这会使性能更差?我说的是大约5000排,很快就会达到100000排,但我怀疑它是否会超过这个数字。提前感谢。@Jachinair-A视图
主要是底层选择
的语法糖;发表看法