zoukankan      html  css  js  c++  java
  • 数据列表(联表查询)优化

    一、情况描述

    我们在做后台数据列表(例如:订单列表、会员列表、活动列表~~之类的)时候,需要的数据往往需要查询两张或以上的数据表,一般情况下会有两种做法

    1)联表查询(在这里先不考虑通过联表方法无法查询到想要的字段数据的情况)

    2)查单表,循环处理查询其他表的信息

    二、两种查询方法比较

    针对以上两种情况呢,一般我们都会以为联表查询会比循环查询要快,其实实际情况并不是这样的,其实查单表,再循环查询其他表反而更快

    这是为什么呢???其实我也不知道哈哈,下面给出一些我自己的猜测(具体哪个更快,建议各位同学自己动手写一下代码做实验!)

    猜测

    1)如果要查询的表数据量比较大,和其他表的关联关系也比较复杂(查一个字段需要关联两张表之类的),这样拼出来的sql语句其实是比较复杂和啰唆的;

    2)联表查询的时候,并不像查单表一样(假设查20条数据)直接就查询返回20条记录的,它内部的关联关系比较复杂,例如订单表的member_id关系显示members表的uname,可能并不像我们用member_id来从members表里查询uname一样快捷,它要处理sql里的关联逻辑判断(具体是怎样我也并不懂~~);

    3)可能你会说“如果用循环来查询,那不就要执行好多个sql语句(一条记录查一次),mysql连接也消耗大量的资源了吗??”;

    4)其实实际上也不完全是这样,mysql连接是要浪费的(下面会有优化方法),不过总查询时间并不会比联表慢。你想一下,当你面对一个很复杂,逻辑很繁琐的问题的时候,相比于硬啃,当复杂问题分解成若干个容易处理的小问题,反而更快

    5)以上都是一脸正经地胡说八道,具体性能如何,自己做实验测试!!

    三、优化循环查询

    上面说到用查单表再循环查询其它表的方法要比联表查询要快,但要消耗比较多的数据库连接,下面我们要说一下如何减少查询次数

    1)循环查询的时候,我们一般都是通过一个id去其他表查询我们需要的数据(例如orders表member_id查询members表uname),每循环一次查询一次;

    2)其实你有没有发现,每次查询的语句都是一样的??(例如:select uname from members where member_id='xxx'),既然是都一样的,那么我们为什么还要每一次都重复等于等于(=)地来查询??mysql不是还是in这个东西吗??

    3)通过上面分析,我们知道,如果是一样的sql语句,只是查询条件值不同的话,干嘛不用in呢??( 例如:select uname from members where member_id in ('1','2') )

    4)以上面案例为例的话,其实我们先循环出所以的member_id,再用in一次性查询所有的uname会更快,也只需要查询一次!!!!

    5)所以剩下的问题就只是怎么把查询出来的uname再重新分配到每一条记录中去了

    6)下面是我的逻辑实现代码, 仅供参考!!!

    /**
         * 更高效的扩展列处理方法
         * add by tujia @2016.11.07
         * expression(表达式)说明
         * 1)前面两个参数是关联表的on条件(例如:rel_id=order_id)
         * 2)第三个参数是你要提取的字段的名字(例如:t_payed)
         * 3)示例:rel_id=order_id=t_payed,member_id=member_id=login_account
         */
        protected function nice_row_data(&$data, $sql, $expression){
            $ttt = explode('=', $expression);
    
            foreach ($data as $key => $value) {
                $ids[] = $value[$ttt[1]];
            }
            $ids = implode("','", $ids);
    
            $sql = sprintf($sql, $ids);
    
            $list       = $this->db->select($sql);
            $temp       = array(); 
            foreach ($list as $key => $value) {
                $temp[$value[$ttt[0]]] = $value[$ttt[2]];
            }
            foreach ($data as $key => $value) {
                $data[$key][$ttt[2]] = isset($temp[$value[$ttt[1]]])? $temp[$value[$ttt[1]]] : 0;
            }
        }

    使用示例:

    $sql = "SELECT `rel_id`,`t_payed` FROM `sdb_ectools_order_bills` ob LEFT JOIN `sdb_ectools_payments` p ON p.`payment_id` = ob.`bill_id` WHERE ob.`rel_id` IN ('%s') AND p.`status`='succ'";
    
    $this->nice_row_data($data, $sql, 'rel_id=order_id=t_payed');

    补充说明:$data 是 已经查询出来的 单表数据

  • 相关阅读:
    java.lang.NoSuchMethodError: org.springframework.web.context.request.ServletRequestAttributes.<init>
    eclipse web项目实际工程路径对应
    java中专业术语详解
    Maven详解
    工作常用
    html页面布局
    jQuery易混淆概念的区别
    Jquery Datagrid
    Jquery EasyUI 动态添加标签页(Tabs)
    sql语句的写法
  • 原文地址:https://www.cnblogs.com/tujia/p/6043113.html
Copyright © 2011-2022 走看看