hbsprogram.com

thủ thuật wordpress ,vps và mình thích thì mình viết thôi

Xin chào các bạn .Có khi nào bạn gặp phải trường hợp cần hiển thi dữ liệu bán hàng cho nhân viên sale xem dữ liệu bán hàng thường trừ việc báo cáo doanh thu hàng tháng thì việc hiển thị dữ liệu cần xem chỉ trong 3 tuần gần nhất hầu như là đầy đủ với 1 người bán hàng bình thường .

Nhưng thực tế khi thiết kế dữ liệu ta thường có mỗi bảng sale hiển thị đầy đủ bản ghi từ đầu đến cuối của hệ thống làm cho server tốn tài nguyên truy vấn và xử lý dữ liệu khi dùng join đến bảng vận chuyển sẽ làm cho dữ liệu trả về sẽ rất lớn mà trong khi thứ chúng ta chỉ cần chiến % rất nhỏ trong đó .

1 Cách xử lý dữ liệu :

Thực tế : code base đã xử dụng datatables để hiển thị dữ liệu .Ưu điểm nhanh với dữ liệu bé,nhẹ phù hợp với đa số dữ liệu khi file generate ra nhỏ  với số lượng lớn sẽ rất chậm .Ở phần video các bạn sẽ thấy .

Yêu cầu khắc phục : Dữ liệu hiển thị cho sale từ 3s đổ xuống

Cách xử lý : Đây là 1 cách xử lý trong vô vàn cách xử lý mà bạn có thể áp dụng . Mình ở đây xử dụng các dùng bảng phụ nhằm giảm số lượng bảng ghi trả về khi join dữ liệu .

Code ban đầu :

$this->load->library('datatables');
        if ($warehouse_id) {
            $this->datatables
                    // có sms_id ->select("{$this->db->dbprefix('sales')}.id as id, DATE_FORMAT({$this->db->dbprefix('sales')}.date, '%Y-%m-%d %T') as date, reference_no,deliveries.do_reference_no,sms_id,deliveries.status, biller, {$this->db->dbprefix('sales')}.customer, sale_status, grand_total, paid, (grand_total-paid) as balance, payment_status, {$this->db->dbprefix('sales')}.attachment, return_id")
                    ->select("{$this->db->dbprefix('sales')}.id as id, DATE_FORMAT({$this->db->dbprefix('sales')}.date, '%Y-%m-%d %T') as date, reference_no,deliveries.do_reference_no,deliveries.status, biller, {$this->db->dbprefix('sales')}.customer, sale_status, grand_total, paid, (grand_total-paid) as balance, payment_status, {$this->db->dbprefix('sales')}.attachment, return_id")
                    ->from('sales')
                    ->join('deliveries', 'deliveries.sale_id=sales.id', 'left')
                    ->where('warehouse_id', $warehouse_id);
        } else {
            $this->datatables
                    ->select("{$this->db->dbprefix('sales')}.id as id, DATE_FORMAT({$this->db->dbprefix('sales')}.date, '%Y-%m-%d %T') as date, reference_no,deliveries.do_reference_no,deliveries.status, biller, {$this->db->dbprefix('sales')}.customer, sale_status, grand_total, paid, (grand_total-paid) as balance, payment_status, {$this->db->dbprefix('sales')}.attachment, return_id")
                    ->from('sales')
                    ->join('deliveries', 'deliveries.sale_id=sales.id', 'left');
        }

Ở đây chúng ta có 2 bảng dữ liệu là sale và deliveries .Theo như code trên tương ứng với truy vấn sql sau :

select * FROM sma_sales LEFT JOIN sma_deliveries ON sma_sales.id = sma_deliveries.sale_id

dưới dây là thời gian thực thi bảng ghi và số row trả về

Và đây là dữ liệu khi áp dụng phương án tạo bảng ghi phụ :

select * FROM sma_sales_400_top LEFT JOIN sma_deliveries_400_top ON sma_sales_400_top.id = sma_deliveries_400_top.sale_id

 

So sánh ta thấy tốc độ trả về là 0.0143 khi chưa tối ưu và 0.005 khi đã tối ưu

Còn về hiệu quả khi thay code bạn có thể xem ở video sau

2 : Code

1 : Tạo bảng ghi tương tự trong database :

CREATE TABLE sma_sales_400_top LIKE sma_sales
CREATE TABLE sma_deliveries_400_top LIKE sma_deliveries

2 : Trong model :

// update dữ liệu sang mảng mới
    public function UpdateDatafromSaletoSales21days($date= 21)
    {
        /* số ngày ở lại và số bảng ghi giới hạn là 400 nếu vượt quá cũng ko lấy
            Tạo 2 bảng 
         * CREATE TABLE sma_deliveries_400_top LIKE sma_deliveries
         * CREATE TABLE sma_sales_400_top LIKE sma_sales
         */
        $start_date = date("Y-m-d H:i:s", strtotime(" -".$date." days"));
        $this->db->empty_table('sales_400_top');
        $this->db->empty_table('sma_deliveries_400_top');
        $sql_query = "INSERT INTO sma_sales_400_top SELECT * FROM sma_sales WHERE sma_sales.date >='".$start_date."' LIMIT 400 ";
        $sql_query_deliveries = "INSERT INTO sma_deliveries_400_top SELECT * FROM sma_deliveries WHERE sma_deliveries.date >='".$start_date."' LIMIT 400 ";
        $query = $this->db->query($sql_query);
        $query_deliveries = $this->db->query($sql_query_deliveries);
        return $query;
    }

Trong controller

if ($warehouse_id) {
           $this->datatables
                   // có sms_id ->select("{$this->db->dbprefix('sales_400_top')}.id as id, DATE_FORMAT({$this->db->dbprefix('sales_400_top')}.date, '%Y-%m-%d %T') as date, reference_no,deliveries_400_top.do_reference_no,sms_id,deliveries_400_top.status, biller, {$this->db->dbprefix('sales_400_top')}.customer, sale_status, grand_total, paid, (grand_total-paid) as balance, payment_status, {$this->db->dbprefix('sales_400_top')}.attachment, return_id")
                   ->select("{$this->db->dbprefix('sales_400_top')}.id as id, DATE_FORMAT({$this->db->dbprefix('sales_400_top')}.date, '%Y-%m-%d %T') as date, reference_no,deliveries_400_top.do_reference_no,deliveries_400_top.status, biller, {$this->db->dbprefix('sales_400_top')}.customer, sale_status, grand_total, paid, (grand_total-paid) as balance, payment_status, {$this->db->dbprefix('sales_400_top')}.attachment, return_id")
                   ->from('sales_400_top')
                   ->join('deliveries_400_top', 'deliveries_400_top.sale_id=sales_400_top.id', 'left')
                   ->where('warehouse_id', $warehouse_id);
       } else {
           $this->datatables
                   ->select("{$this->db->dbprefix('sales_400_top')}.id as id, DATE_FORMAT({$this->db->dbprefix('sales_400_top')}.date, '%Y-%m-%d %T') as date, reference_no,deliveries_400_top.do_reference_no,deliveries_400_top.status, biller, {$this->db->dbprefix('sales_400_top')}.customer, sale_status, grand_total, paid, (grand_total-paid) as balance, payment_status, {$this->db->dbprefix('sales_400_top')}.attachment, return_id")
                   ->from('sales_400_top')
                   ->join('deliveries_400_top', 'deliveries_400_top.sale_id=sales_400_top.id', 'left');
       }