解决数据导出关闭mysql问题

2 篇文章 0 订阅
最近有个项目老是在周一自动关闭mysql,必须得手动启动,查询日志后发现是内存溢出造成LINUX优先关闭了mysql服务
查看具体方法,发现后台有个订单导出execl造成的
使用的是**CRMEB**商城,**TP6**框架,这个订单导出需要关联用户表和购物车表,三表联查后一次性导出1万条数据就会崩溃,当然也是服务器配置一般,内存只分了1G给PHP,导出速度也很慢,然后找了很久找到一个导出CSV,用了下挺好用的,速度快,也不会早晨内存溢出,下面记录下具体使用
可以使用ajax请求
转载[原有压缩解压功能我没有使用](https://www.cnblogs.com/panziwen/p/12505170.html)

    public static function excel_out($where)
    {
        //不限制执行时间,以防超时
        set_time_limit(0);
        //文件名
        $xlsName = '订单导出' . date('YmdHis', time());
        //表头
        $xlsCell = ['编号', '订单号', '收货人', '收货人手机', '收货人地址', '支付金额', '使用积分', '备注', '购买人', '购买人手机', '订单状态', '下单时间', '商品信息'];
        //统计总行数 getOderWhere是处理条件的,就不放了
        $sqlCount = self::getOrderWhere($where, self::alias('a')
            ->join('user r', 'r.uid=a.uid', 'LEFT'), 'a.', 'r')
            ->count();

        //每次取多少条
        $sqlLimit = 1000;//每次只从数据库取1000条

        // buffer计数器
        $cnt = 0;

        $fileNameArr = array();

        //分段执行,以免内存写满
        for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) {
            $fp = fopen($xlsName . '_' . $i . '.csv', 'w'); //生成临时文件

            $fileNameArr[] = $xlsName . '_' . $i . '.csv';//将临时文件保存起来

            //第一次执行时将表头写入
            if ($i == 0) {
                fputcsv($fp, $xlsCell);
            }

            //查询出数据
            $xlsData = self::getOrderWhere($where, self::alias('a')
                ->join('user r', 'r.uid=a.uid', 'LEFT'), 'a.', 'r')
                ->field('a.id,a.order_id,a.real_name,a.user_phone,a.user_address,a.pay_price,a.use_integral,a.remark,r.nickname,r.phone,a.add_time,a.status,a.shipping_type,a.goods_id,a.total_num')
                ->limit($i * $sqlLimit, $sqlLimit)
                ->select()->toArray();

            foreach ($xlsData as $v) {
                $cnt++;
                //执行下一次循环之前清空缓冲区
                if ($sqlLimit == $cnt) {
                    ob_flush();
                    $cnt = 0;
                }
               if ($v['status'] == 2 && $v['shipping_type'] == 2) {
                    $v['status_name'] = '未核销';
                } else if ($v['status'] == 2) {
                    $v['status_name'] = '未发货';
                } else if ($v['status'] == 3) {
                    $v['status_name'] = '待收货';
                } else if ($v['status'] == 4) {
                    $v['status_name'] = '待评价';
                } else if ($v['status'] == 5) {
                    $v['status_name'] = '已完成';
                } else {
                    $v['status_name'] = '已取消';
                }
                //这里查询订单的商品详情信息
                $goods = Db::name('store_product')->where('id', $v['goods_id'])->field('id,store_name,unit_name,price')->find();
                $goods_str = '名称:' . $goods['store_name'] . "\r\n";
                $goods_str .= '价格:' . $goods['price'] . "\r\n";
                $goods_str .= '数量:' . $v['total_num'] . ' ' . $goods['unit_name'];
                $v['add_time'] = date('Y-m-d H:i:s', $v['add_time']);
                $v['goods_str'] = $goods_str;

                $item = [
                    $v['id'],
                    $v['order_id'],
                    $v['real_name'],
                    $v['user_phone'],
                    $v['user_address'],
                    $v['pay_price'],
                    $v['use_integral'],
                    $v['remark'],
                    $v['nickname'],
                    $v['phone'],
                    $v['status_name'],
                    $v['add_time'],
                    $goods_str,
                ];
                unset($v);

                //每行写入到临时文件
                fputcsv($fp, $item);
            }
            fclose($fp);  //每生成一个文件关闭
        }

        //将所有临时文件合并成一个
        foreach ($fileNameArr as $file) {
            //如果是文件,提出文件内容,写入目标文件
            if (is_file($file)) {
                $fileName = $file;
                //打开临时文件
                $handle1 = fopen($fileName, 'r');
                //读取临时文件
                if ($str = fread($handle1, filesize($fileName))) {
                    //关闭临时文件
                    fclose($handle1);
                    //打开或创建要合并成的文件,往末尾插入的方式添加内容并保存
                    $handle2 = fopen($xlsName . '.csv', 'a+');
                    //写入内容
                    if (fwrite($handle2, $str)) {
                        //关闭合并的文件,避免浪费资源
                        fclose($handle2);
                    }
                }
            }
            unlink($file); //删除csv临时文件
        }

        //输出压缩文件提供下载
        header("Cache-Control: max-age=0");
        header("Content-Description: File Transfer");
        header('Content-disposition: attachment; filename=' . basename($xlsName.'.csv')); // 文件名
        header("Content-Type: application/zip"); // zip格式的
        header("Content-Transfer-Encoding: binary"); //
        header('Content-Length: ' . filesize($xlsName.'.csv')); //
        @readfile($xlsName.'.csv');//输出文件;
        unlink($xlsName . '.csv'); //删除合并的临时文件
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Eclipse中导出MySQL数据,你可以按照以下步骤进行操作: 1. 首先,确保你已经在Eclipse中安装了MySQL的JDBC驱动程序。如果没有安装,你可以从MySQL官方网站下载并安装。 2. 在Eclipse中创建一个新的Java项目或打开一个已有的Java项目。 3. 在项目中创建一个新的Java类,用于编写导出数据的代码。 4. 在Java类中导入所需的包包括`java.sql.*`和`java.io.*`。 5. 在代码建立与MySQL数据库的连接。你需要提供数据库的URL、用户名和密码。例如: ```java String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; Connection conn = DriverManager.getConnection(url, username, password); ``` 6. 创建一个``对象,并执行SQL查询语句来获取要导出数据。例如: ```java Statement stmt = conn.createStatement(); String sql = "SELECT * FROM mytable"; ResultSet rs = stmt.executeQuery(sql); ``` 7. 创建一个`BufferedWriter`对象,用于将数据写入到文件中。例如: ```java BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt")); ``` 8. 遍历查询结果集,并将每一行数据写入到文件中。例如: ```java while (rs.next()) { String data = rs.getString("column1") + "," + rs.getString("column2"); writer.write(data); writer.newLine(); } ``` 9. 关闭结果集、语句和连接。例如: ```java rs.close(); stmt.close(); conn.close(); ``` 10. 关闭文件写入器。例如: ```java writer.close(); ``` 11. 完成导出数据的操作。 这是一个简单的示例,你可以根据自己的需求进行修改和扩展。同时,你也可以使用第三方库,如Apache POI或CSV库,来更方便地导出数据Excel或CSV文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值