获取单个大记录,或获取多个小记录?

时间:2011-02-28 19:49:49

标签: php mysql database scaling

我想知道对于我的服务器(速度等)有什么好处,考虑CPU,带宽和磁盘空间使用情况。

目前我的服务器即将爆炸,MySQL / PHP请求太多,等等,这就是我正在优化我的应用程序的原因(在这个问题中讨论:Best way to scale data, decrease loading time, make my webhost happy)。

现在,减少CPU,带宽和磁盘空间使用的最佳解决方案是什么?

  

1)从a获取一个大记录   表(100.000+记录,让我们说   20kb /记录)并处理获取   PHP =>只有1个请求,但结果   可能导致服务器负载过重?

     

2)从a中获取多个小记录   表(1.000.000+记录,让我们说   1kb / record)=>显着更多的MySQL   需要获得相同结果的请求   作为方法1的结果

方法1将导致数据库变为大量GB(10+)。使用方法2,数据库将更小,但我不确定运行大量查询对我的应用程序性能的影响?

从1.000.000+记录的表中返回mysql_result()需要更多时间,因为它需要扫描特定记录的所有行?

希望您能告诉我哪种方法可以减少CPU,带宽和磁盘空间的使用!

修改

我目前有一张桌子:facebook_id,friends_json。 在friends_json中,存储此facebook_id用户的每个朋友的uid AND名称。使用这种方法,每条记录大约10kb。一旦请求了这条记录,我就不必另外请求获取朋友的名字:这已经包含在friends_json中。

我的问题是,仅将朋友的uid存储在friends_json中是否更好,这样每位朋友都必须对另一个表(friends_names)运行查询,以从此表中获取此朋友的姓名(如果不可用,请求从Facebook)。第二种方法可以节省磁盘空间,但在向用户显示结果之前,我真的需要做大量的请求。

目标是我必须将数据库中的朋友列表与当前的朋友列表进行比较。如果用户删除了他/她的Facebook个人资料,我就不能再请求相应的名字,这就是我必须在我的数据库中保存姓名的原因。

2 个答案:

答案 0 :(得分:2)

由于问题不够明确(或者我无法正确理解),我认为你有1个表有2列:facebook_id,friends_json,你正在请求朋友的所有朋友。这是我能想到的最糟糕的情况。你还要做的就是2个简单的查询:

  1. 获得1个索引命中的主题,然后从json解码它获取uid
  2. 使用ids获取所有朋友的朋友列表并使用“in”查询,然后将它们全部推送到地图中以消除重复项。
  3. 以上查询都不需要扫描整个表(最糟糕的情况)

    如果您可以提供有关表格结构和目标(您希望从该数据中检索的内容)的更多信息,我们可以提供更多帮助。

    编辑:如果您必须在每次点击中进行表扫描,那么没有什么可以保存您的服务器。

    修改

      

    我目前有一张桌子:   facebook_id,friends_json。在   friends_json,uid和的名字   这个facebook_id用户的每个朋友   被储存了。每个人都使用这种方法   记录大约10kb。一旦这个记录   请求,我没有额外做   请求获取a的名称   朋友:这已经包括在内了   friends_json。

         

    我的问题是它是否更好   只存储朋友的uid   friends_json,这样每个朋友   我必须对另一个表运行查询   (friends_names)获取名称   这张桌子上的朋友(如果不是   可用,从Facebook请求)。   第二种方法节省了磁盘空间,   但我真的需要做大量的工作   在我可以向用户显示之前的请求   结果。

         

    目标是我必须比较   我的数据库中的朋友列表   目前的朋友列表。如果是用户   删除他/她的Facebook个人资料,我   无法请求相应的名称   这就是为什么我必须保存   我的数据库中的名字。

    只要您通过点击索引获得结果,表格的大小或行不会像您想象的那样影响。当你保持uid的标准化时,只是为了得到名字的联接不是要走的路。你用“uid,name”列和友谊表“uid1,uid2”保存“用户”表,或者你有标准化的数据,包括uid和name。关于新老朋友列表的比较,你应该在php中使用uid(而不是名字)来做。从facebook获取好友列表,将其与当前好友列表进行比较,找出差异并应用于数据库。在这种情况下,您不必在应用程序的任何位置进行表扫描。

    这是正常的做法(没有json):

    fb_users 表:uid,name,is_app_user(PK:uid) fb_friends 表:uid1,uid2(PK:uid1,uid2)

    获取好友sql查询:

    SELECT ff.uid1, fu.name FROM fb_friends ff
    LEFT JOIN fb_users fu ON ff.uid1 = fu.uid
    WHERE ff.uid2 = $FBID 
    UNION
    SELECT ff.uid2, fu.name FROM fb_friends ff
    LEFT JOIN fb_users fu ON ff.uid2 = fu.uid
    WHERE ff.uid1 = $FBID
    

    并且为了添加用户,你可以做一个巧妙的技巧来每次更新名称以更改名称(大部分时间都在使用):

    INSERT INTO fb_users(uid,name) 
    VALUES 
    ($FBUD1, $FBNAME1), 
    ($FBUD2, $FBNAME2) 
    ...
    ON DUPLICATE KEY name = VALUES(name)
    

    并添加朋友,你也可以做一个技巧,所以你不必担心同时有A B和B A:

    INSERT IGNORE INTO fb_friends(uid, uid1) VALUES(" . min($uid, $uid1) . ", " . max($uid, $uid1) . ");
    

    如果您决定保持数据关系,这些只是技巧,但我建议保持规范化。你的json方法在大多数情况下是使用的,并且不用担心空间很多,因为数据大小通常不是阻塞服务器的东西,它是你请求数据(代码)的方式和你抓取它的方式( sql查询)是你应该调整的地方。

答案 1 :(得分:0)

始终以较小的份额请求您所需的内容。用户可以通过在键盘上按ESC来中断脚本执行[除非你有ignore_user_abort()]。所以慢慢稳定。