如何更快地检索500k记录数据库数据?

时间:2017-11-30 06:48:18

标签: mysql laravel laravel-5.2

我有两张表T1 1 000条记录,T2有500 000条记录。我有一个查询,我在它们之间运行连接并通过执行一些聚合来获取数据。我的页面似乎加载缓慢。有没有办法让这个查询更快?

我在正在执行聚合的列上创建了索引。我认为这是一个通用声明。

      $query = Mymodel::selectRaw("supplier_data.name as distributor,supplier_data.name as name, supplier_data.group_id as group_id, supplier_data.pay,supplier_data.group_id as submitted_group_plan,supplier_data.group_id as group_id_string,
            (SELECT sum(t.net_claim) AS trans_number 
            FROM transactions_data_new as t 
            JOIN  `supplier_data` AS d ON  `t`.`member_id` =  `d`.`group_id`
            WHERE
            (
                (
                t.`submit_date`>= '$date_from' and t.`submit_date`<= '$date_to' 
                AND t.`member_id` = supplier_data.group_id
                )
                OR
                (
                    (t.claim_status  IS NULL)
                    AND
                    (t.submit_date is NULL)
                )
            )
            AND d.id = supplier_data.id
        ) as trans_number,


        (SELECT sum(t.claim) AS trans_number 
            FROM transactions_data_new as t 
            JOIN  `supplier_data` AS d ON  `t`.`member_id` =  `d`.`group_id`
            WHERE
            (
                (
                t.`submit_date`>= '$date_from' and t.`submit_date`<= '$date_to' 
                AND t.`member_id` = supplier_data.group_id
                )
                OR
                (
                    (t.claim_status  IS NULL)
                    AND
                    (t.submit_date is NULL)
                )
            )
            AND d.id = supplier_data.id
        ) as claim,

        (SELECT sum(t.reversed) AS trans_number 
            FROM transactions_data_new as t 
            JOIN  `supplier_data` AS d ON  `t`.`member_id` =  `d`.`group_id`
            WHERE
            (
                (
                t.`submit_date`>= '$date_from' and t.`submit_date`<= '$date_to' 
                AND t.`member_id` = supplier_data.group_id
                )
                OR
                (
                    (t.claim_status  IS NULL)
                    AND
                    (t.submit_date is NULL)
                )
            )
            AND d.id = supplier_data.id
        ) as reversed,

        (SELECT sum(t.reversal) AS trans_number 
            FROM transactions_data_new as t 
            JOIN  `supplier_data` AS d ON  `t`.`member_id` =  `d`.`group_id`
            WHERE
            (
                (
                t.`submit_date`>= '$date_from' and t.`submit_date`<= '$date_to'
                AND t.`member_id` = supplier_data.group_id
                )
                OR
                (
                    (t.claim_status  IS NULL)
                    AND
                    (t.submit_date is NULL)
                )
            )
            AND d.id = supplier_data.id
        ) as reversal
            "); 

2 个答案:

答案 0 :(得分:3)

我没有看到这个过于复杂/重复的需要,同一个子句和同一个表的多个子选择可以使用单个左连接来完成

SELECT 
  s.name AS distributor,
  s.name AS name,
  s.group_id AS group_id,
  s.pay,
  s.group_id AS submitted_group_plan,
  s.group_id AS group_id_string,
  SUM(t.net_claim) AS trans_number,
  SUM(t.claim) AS claim,
  SUM(t.reversed) reversed,
  SUM(t.reversal) reversal 
FROM
  supplier_data s 
  LEFT JOIN transactions_data_new t 
    ON `t`.`member_id` = s.`group_id` 
    AND (
      (
        t.`submit_date` >= '$date_from' 
        AND t.`submit_date` <= '$date_to'
      ) 
      OR (
        t.claim_status IS NULL 
        AND t.submit_date IS NULL
      )
    ) 
GROUP BY s.name,
  s.group_id,
  s.pay 

答案 1 :(得分:0)

据我所知,chunk()方法适用于需要使用大型数据集并按块执行该数据块的操作。

从你的问题来看,听起来你正在执行一个查询然后将数据作为JSON返回给我,听起来并不像你在数据集上采取需要分块的操作

如果你想要分解返回的JSON数据,你应该看看分页。

您可以像这样对您的查询应用分页:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->paginate();

您可以通过将数字传递给paginate方法来指定每个集合的大小:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->paginate(25);

如果我误解了你确实想要进行分块,我相信你可以做到以下几点:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->chunk(50, function($inspectors) {
        foreach ($inspectors as $inspector) {
            // apply some action to the chunked results here
        }
    });

此外,如果您要返回一个雄辩的对象,它将自动转换为json,因此您不需要执行json_encode(),因为我知道。