分组记录的最快方法是什么?

时间:2013-03-03 10:23:27

标签: mysql sql database-design

我的网站显示了不同主题的链接集合。这些链接分为两种类型:Web和图像。我的数据库将拥有数百万(可能超过一千万)这些记录。当页面加载时,我需要向用户显示该页面特定主题的Web和图像链接。所以第一个问题是:

  1. 我是否创建了两个单独的较小的表,每个表用于Web和图像链接,然后对每个表进行查询,或者为两者创建一个巨大的表(具有正确的索引)并进行一个查询。我会在哪里获得更好的表现?如果一个表和一个查询更有效,那么我的下一个问题是:

  2. 将两种类型细分为演示文稿的最有效方法是什么?我应该使用group by,还是应该使用php将结果数组分成两种类型?

  3. TIA!

4 个答案:

答案 0 :(得分:3)

您可以使用所有对象的表格或链接或网站的表格获得类似的表现。如果您有两个单独的表,那么执行结果的UNION将返回您需要的所有结果。

划分结果的主要原因是它们是否真的不同(从您的应用角度来看)。也就是说,如果你最终会使用很多像

这样的查询
select * from objects where type='image';

然后有两个表可能是有意义的。

然后使用group by不是对不同结果进行分组的一种方式,它是一种聚合它们的方式。

因此,例如,您可以使用

select type, count(*) from objects group by type

获取

| image |  100000 |
| web   | 2000000 |

但它不会返回分隔的对象。要使它们“分组”,您可以对每个查询使用查询,也可以使用排序,然后在应用程序中使用逻辑来划分结果。

答案 1 :(得分:1)

这取决于网络数据如何接近img数据。如果数据基本上是由链接组成的,那么一个表更适合,有一个列可以区分Web和数据(以及后面可能有的其他表,如css,js ......)

Links: (id, link, type)

类型类型链接上添加索引将有助于分组(按类型)和匹配搜索(类型,链接)。

但是,如果网页和img数据不同,你不想混合苹果和橘子,比如

Web: (wid, wlink, rating, ...)
Img: (iid, ilink, width, height, mbsize, camera, datetaken, hasexif...)

在这种情况下,除了链接之外,两个表没有太多共同之处。图像链接和网络链接不同,当两种数据具有相同的链接时甚至没有“增益”。另一个优点(一个表也可以,但在这里更有意义)是在另一个表中链接两种数据

 Relations: (wid,iid)

允许维护网站和图像之间的关系,因为图像可能被多个网站使用,并且网站使用多个图像。在widiid上建立索引。

我的偏好是两个表(带有可选的“关系”链接)。

关于来自PHP的查询,使用UNION,您可以在一个查询中从两个表中获取数据。

答案 2 :(得分:1)

您可能只从一个表中获得略微更好的性能,但这个决定应该主要取决于数据或约束的性质是否不同。

还有另一个(从性能角度来看更重要)您必须做出的决定:您希望如何cluster数据(所有InnoDB tables are clustered)?

如果您想获得一个特定页面的所有链接的出色表现,请使用标识关系,在链接表中生成一个自然键:

enter image description here

LINK表实际上只是一个B树,页面PK 1 位于前沿,它将属于同一行的行物理组合在一起页。通过简单的索引范围扫描和最小I / O可以满足以下查询:

SELECT URL
FROM LINK
WHERE PAGE_ID = <whatever>

如果您使用单独的表,则可以只有两个不同的查询。许多客户端API支持在单个数据库往返中执行两个查询。如果PHP没有,你可以UNION两个查询来保存一个数据库往返:

SELECT *
FROM (
    SELECT 1 LINK_TYPE, URL
    FROM IMAGE_LINK
    WHERE PAGE_ID = <whatever>
    UNION ALL
    SELECT 2, URL
    FROM WEB_LINK
    WHERE PAGE_ID = <whatever>
)
ORDER BY LINK_TYPE

以上查询将为您提供......

LINK_TYPE  URL
1          http://somesite.com/foo.jpeg
1          http://somesite.com/bar.jpeg
1          http://somesite.com/baz.jpeg
...
2          http://somesite.com/foo.html
2          http://somesite.com/bar.html
2          http://somesite.com/baz.html
...

...在客户端级别很容易分开。

如果您没有使用单独的表,您可以在客户端级别通过扩展名分隔URL,或者在LINK PK中引入其他字段:{PAGE_ID,LINK_TYPE,URL},这应该进行以下查询非常有效:

SELECT LINK_TYPE, URL
FROM LINK
WHERE PAGE_ID = <whatever>
ORDER BY LINK_TYPE

请注意,PK中的字段顺序很重要,因此将LINK_TYPE放在最后会阻止DBMS 进行索引范围扫描。


1 无论它是什么;我只是以PAGE_ID为例。

答案 3 :(得分:0)

  

我是创建两个单独的较小的表还是一个巨大的表?

去一张桌子。

  

将两种类型细分为演示文稿的最有效方法是什么?

取决于某些搜索条件。