是否可以缩短此查询

时间:2019-11-16 16:48:14

标签: sql laravel eloquent

我们使用循环在时间戳之间进行读取。这行得通,但是用这种方式耗尽了具有百万条记录的服务器。

时间戳由$ resolution变量确定,并分配给新数组。但是我们知道这是糟糕的方法。我想我们可以很快做到。也许一个查询就够了。

Route::get('/history', function (Request $request) {

    //return response()->json([]);

    $symbol = explode("-", $request->get("symbol"));
    $coin = Coin::where("symbol", $symbol[1])->first();
    $currency = Coin::where("symbol", $symbol[0])->first();

    $resolution = $request->get("resolution");
    $from = $request->get("from");
    $to = $request->get("to");

    $uniqueKey = sprintf("OHLCKEY%s%s%s%s",
        $symbol[0], $symbol[1],
        Carbon::createFromTimestamp($from)->second(0)->timestamp,
        Carbon::createFromTimestamp($to)->second(0)->timestamp);
    $redis=Redis::connection();
    $cache = $redis->get($uniqueKey);


    if($cache) {
        $data = json_decode($cache);
        return response()->json($data);

    } else {

        $t = [];
        $o = [];
        $h = [];
        $l = [];
        $c = [];
        $v = [];
        $s = "no_data";

        $minMaxDates = TransactionDetail::where("type", "buy")
            ->whereBetween("created_at", [
                Carbon::createFromTimestamp($from),
                Carbon::createFromTimestamp($to)
            ])->where("coin_id", $coin->id)->where("currency_id", $currency->id)
            ->selectRaw("min(created_at) as minDate, max(created_at) as maxDate")->first();

        if($minMaxDates->minDate) {
            $minDate = Carbon::createFromTimeString($minMaxDates->minDate)->timestamp;
            if($from < $minDate) {
                $startDate = $minDate;
            } else {
                $startDate = (int)$from;
            }

            $maxDate = Carbon::createFromTimeString($minMaxDates->maxDate)->timestamp;
            if($to > $maxDate) {
                $to = $maxDate;
            }

            while ($startDate < $to):
                switch ($resolution) {
                    case "30";
                        $endDate = Carbon::createFromTimestamp($startDate)->addMinutes(30)->timestamp;
                        break;
                    case "60";
                        $endDate = Carbon::createFromTimestamp($startDate)->addHour(1)->timestamp;
                        break;
                    case "180";
                        $endDate = Carbon::createFromTimestamp($startDate)->addHour(3)->timestamp;
                        break;
                    case "360";
                        $endDate = Carbon::createFromTimestamp($startDate)->addHour(6)->timestamp;
                        break;
                    case "720";
                        $endDate = Carbon::createFromTimestamp($startDate)->addHour(12)->timestamp;
                        break;
                    default:
                        $endDate = Carbon::createFromTimestamp($startDate)->addHour(1)->timestamp;
                        break;
                }
                if ($endDate > $to) $endDate = $to;

                $transactions = TransactionDetail::where("type", "buy")
                    ->whereBetween("created_at", [
                        Carbon::createFromTimestamp($startDate),
                        Carbon::createFromTimestamp($endDate)
                    ])->where("coin_id", $coin->id)->where("currency_id", $currency->id)->get();

                if (!$transactions->isEmpty()) {
                    $t[] = $transactions->first()->created_at->timestamp;
                    $o[] = floatval($transactions->first()->price);
                    $h[] = floatval($transactions->max("price"));
                    $l[] = floatval($transactions->min("price"));
                    $c[] = floatval($transactions->last()->price);
                    $v[] = floatval($transactions->sum("amount"));
                }

                $startDate = $endDate + 1;
            endwhile;
        }

        if (!empty($t)) $s = "ok";
        $data = ["t" => $t, "o" => $o, "h" => $h, "l" => $l, "c" => $c, "v" => $v, "s" => $s];

        $redis->set($uniqueKey, json_encode($data));
        return response()->json($data);
    }
});

我们可以使用一个mysql查询重现此代码吗? 预先谢谢你。

0 个答案:

没有答案