V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pyengwoei
V2EX  ›  程序员

前端每秒刷新的 PHP 接口文件,取同一数据库 5 张不同表里面的数据。

  •  
  •   pyengwoei · 2016-09-12 15:05:40 +08:00 · 4241 次点击
    这是一个创建于 2990 天前的主题,其中的信息可能已经有所发展或是发生改变。
    是用在一个 PHP 文件里面去把五张表的数据取好,然后组合成一个 string 返回给前端,还是做成 5 个 PHP 文件,每次取一张表数据分别返回好?
    我现在是用的前面的方法,但是感觉有部分表里面的数据很慢,不及时。
    难道是我 SQL 语句的问题吗?
    $shoehistory=mysql_query("select * from table1 ORDER BY id DESC LIMIT 0,1 ");
    $current=mysql_query("select * from table2 ORDER BY id DESC LIMIT 0,1 ");
    $time=mysql_query("select * from table3 ORDER BY id DESC LIMIT 0,1 ");
    $gamestatus=mysql_query("select * from table4 ORDER BY id DESC LIMIT 0,1 ");
    $jieguo = "";
    while ($row=mysql_fetch_array($shoehistory)) {
    //echo $row[6];
    $jieguo=$row[6];
    }
    while ($row=mysql_fetch_array($current)) {
    //echo "|".$row[7]."#".$row[8]."#".$row[9]."#".$row[10]."#".$row[11]."#".$row[12];
    $jieguo = $jieguo. "|".$row[7]."#".$row[8]."#".$row[9]."#".$row[10]."#".$row[11]."#".$row[12];
    }
    while($row2=mysql_fetch_array($time)){
    //echo "|".$row2[5];
    $jieguo = $jieguo. "|".$row2[5];
    }
    while ($row=mysql_fetch_array($gamestatus)) {
    $jieguo = $jieguo. "|". $row[7];
    //echo $row[7];
    }
    echo $jieguo;
    37 条回复    2016-09-14 13:45:26 +08:00
    ytmsdy
        1
    ytmsdy  
       2016-09-12 15:39:24 +08:00
    不要用 select *,最好要的字段都给带上。万一你的表里面有一个特别大的字段,然后你又用不到,这时间开销那就酸爽了。
    imnpc
        2
    imnpc  
       2016-09-12 15:51:47 +08:00
    1.给数据表查询较多的字段加上索引
    2.只查询必须的字段
    pyengwoei
        3
    pyengwoei  
    OP
       2016-09-12 15:54:49 +08:00
    @ytmsdy 不用 select? 可以简单写一个例子吗
    pyengwoei
        4
    pyengwoei  
    OP
       2016-09-12 15:55:50 +08:00
    @imnpc 加索引是加一个 ID 吗? 只查询必须的字段这个我明白,确实这里有问题 感谢了
    pyengwoei
        5
    pyengwoei  
    OP
       2016-09-12 15:59:53 +08:00
    @imnpc 请问一下,排除 SQL 语句,我的第一种做法,和第二种做法哪一种好些啦
    shakyamuni
        6
    shakyamuni  
       2016-09-12 16:00:54 +08:00
    加索引,使用长轮寻。
    keikeizhang
        7
    keikeizhang  
       2016-09-12 16:02:58 +08:00
    这个事情有 laravel 框架分分钟解决
    former
        8
    former  
       2016-09-12 16:04:19 +08:00
    可以试试 websocket
    ten789
        9
    ten789  
       2016-09-12 16:04:31 +08:00
    1 个比 5 个好 cache 最好
    pyengwoei
        10
    pyengwoei  
    OP
       2016-09-12 16:05:30 +08:00
    @keikeizhang 现在是小项目,前端 HTML 才 100 多行代码,后台 PHP 文件也才 80 多行。。
    pyengwoei
        11
    pyengwoei  
    OP
       2016-09-12 16:07:12 +08:00
    @ten789 是啊,只是现在项目才开始,现在是以搞出来为目的,后期稳定了再进去升级
    imlewc
        12
    imlewc  
       2016-09-12 16:13:56 +08:00
    @keikeizhang 这个跟框架什么关系 这么推荐 laravel 是不是有点牵强了 缓存可以试下
    ytmsdy
        13
    ytmsdy  
       2016-09-12 16:33:55 +08:00
    @pyengwoei 我的意思是不要用 * 不是不要用 select !!
    pangliang
        14
    pangliang  
       2016-09-12 16:42:19 +08:00
    你这些在意义上都是缓存数据, 所以你放 mysql 再查出最后一行来, 当然别扭; 上 memcache 或者 redis
    pyengwoei
        15
    pyengwoei  
    OP
       2016-09-12 16:45:55 +08:00
    @pangliang 是的,数据是在实时更新的,每次取最新的数据
    dream7758521
        16
    dream7758521  
       2016-09-12 16:47:22 +08:00 via Android
    @ytmsdy 这里就你的靠谱,其他人一上来,就推荐屠龙秘籍
    pyengwoei
        17
    pyengwoei  
    OP
       2016-09-12 16:58:41 +08:00
    @dream7758521 也不是 大家看到的问题不同,@ytmsdy 的最简单直接而已 呵呵, select * 这里确实有问题
    laobaozi
        18
    laobaozi  
       2016-09-12 17:15:18 +08:00
    每次都从 5 张表里取最新的第一条,不知道这 5 个第一条是不是有什么联系
    第一是考虑,如果能将这 5 条合并到一张表或者能找到合适的字段做外联,那么一次 sql 的执行全部查出来将提高不少效率
    第二就是缓存 sql 结果,更新数据时清除再缓存
    pyengwoei
        19
    pyengwoei  
    OP
       2016-09-12 17:20:16 +08:00
    @laobaozi 好的,我仔细想想,看来 SQL 这里 有很大的提高空间。
    “”第二就是缓存 sql 结果,更新数据时清除再缓存“” 这个的意思是,不用每次都插入新的一条数据,表里面只留最新的数据的意思吗? 我现在好像确实表里面有几万数据了
    akira
        20
    akira  
       2016-09-12 17:20:36 +08:00
    id 肯定是自增索引吧,先取 max id ,再取对应行的数据会快很多
    sherlocktheplant
        21
    sherlocktheplant  
       2016-09-12 17:27:58 +08:00
    加一层内存缓存就好了 反正只需要最新数据 插入数据的时候再更新内存缓存
    或者直接磁盘缓存也可以 直接把需要的结果写到磁盘里的一个或者五个文件里 如果是一个文件就需要自己定格式 简单的格式就是换行符分割数据 跟内存数据一样 其他地方插入数据的时候 除了入库还需要更新缓存文件
    mengxy
        22
    mengxy  
       2016-09-12 17:43:35 +08:00
    @former 呵呵,您真厉害,还知道 websocket 呢,也不看看人家问的问题到底是什么
    laobaozi
        23
    laobaozi  
       2016-09-12 17:43:55 +08:00
    缓存结果是指 将 select 得到的结果用文件或者内存缓存,以文件缓存为例:
    1.创建一个文件缓存的方法, 定义
    AddFileCache()
    GetFileCache()
    DelFileCache()
    三个方法,以表名为参数;

    2.在接到请求时,首先调用尝试从缓存中取,没取到再查数据库,以取
    {
    $shoehistory = GetFileCache() ;
    if(没缓存){
    $shoehistory = 查数据库
    AddFileCache($result)
    }

    //同理取别的参数

    }


    3,如果有数据更新,在 insert 完成后调 DelFileCache()
    wobuhuicode
        24
    wobuhuicode  
       2016-09-12 17:48:48 +08:00
    @keikeizhang 分分钟就太慢了~~查询都是按照毫秒算的
    pyengwoei
        25
    pyengwoei  
    OP
       2016-09-12 18:00:59 +08:00
    @sherlocktheplant 这个学到了,以后可以试试
    pyengwoei
        26
    pyengwoei  
    OP
       2016-09-12 18:04:18 +08:00
    @laobaozi 感谢了,这个是文件缓存对吧,就是建立一个实体文件,每次的最新数据就放文件里面?
    还 有种是内存缓存对吧?
    laobaozi
        27
    laobaozi  
       2016-09-12 18:24:58 +08:00
    harker
        28
    harker  
       2016-09-12 18:30:05 +08:00
    没有什么大问题,记录一下 mysql 语句的执行时间记录,看看是哪条慢,再想办法优化
    sfree2005
        29
    sfree2005  
       2016-09-12 22:12:20 +08:00 via iPhone
    有实时性高的需求可以考虑用 firebase 或者 RethinkDB 。 可以完全代替也可以作为辅助, 看情况而定。
    Septembers
        30
    Septembers  
       2016-09-13 02:54:24 +08:00 via iPad
    https://github.com/igorw/EventSource
    用 EventSource 主动推?
    pangliang
        31
    pangliang  
       2016-09-13 09:38:10 +08:00
    如果你说的是不想挂那么多别的东西; 就 mysql 的话, 那你这个应该做一张 kv 结构 的表; 一种状态数据就只有一行; 加上你这个就是"其他系统更新状态" "这个系统读取" , 甚至可以考虑使用 mysql 内存表

    你这个从业务逻辑上来讲, 既没有使用历史数据的需求, 也没有计算历史数据关系的需求; 所以, 你用"关系数据库", 还保存那么多历史数据, 本来就是多余的;

    程序=数据结构+算法 ; 数据结构不对, 算法再怎么优化; 事倍功半
    former
        32
    former  
       2016-09-13 09:58:29 +08:00
    @mengxy 确是非问之答,只是看题主对数据的实时性要求很高顺口提下而已
    zybdfdz
        33
    zybdfdz  
       2016-09-13 10:45:32 +08:00
    看都不用看,设计有问题
    pyengwoei
        34
    pyengwoei  
    OP
       2016-09-13 14:30:12 +08:00
    @zybdfdz 请指教一下
    pyengwoei
        35
    pyengwoei  
    OP
       2016-09-13 14:32:00 +08:00
    @pangliang 是的,谢谢提出,感觉确实问题多多
    wizardforcel
        36
    wizardforcel  
       2016-09-14 08:26:47 +08:00   ❤️ 1
    首先要优化查询,比如用 join 连成一张表。四个子句很麻烦,但是要比你现在的五次查询效率高。

    你写在五个函数或者写在一个里面效率都差不多。分到五个文件的话要 include ,可能会损失效率。

    索引在 mysql 里是用 key 声明的东西, mysql 会自动为 where 后面的东西加索引,你可以开 workbench 看看。(如果不用 mysql 就当我没说)

    缓存就是先部署好 redis 或 mc ,然后某个表读取的时候把数据存里面一份,之后从里面读,写的时候让它失效。(当然也可以细化到行)。
    pyengwoei
        37
    pyengwoei  
    OP
       2016-09-14 13:45:26 +08:00
    @wizardforcel 感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3460 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:45 · PVG 19:45 · LAX 03:45 · JFK 06:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.