我正在做一个执行各种事情的ajax请求,并且它需要永远加载。在进行了一些挖掘以找出瓶颈所在之后,我发现使用Eloquent构建查询的速度非常慢。
这是我正在构建的原始查询:
SELECT
`events`.`id`,
FROM_UNIXTIME(
EVENTS.event_datetime,
"%a %D %b %H:%i"
) AS DATETIME,
CONCAT(
countries.name,
" ",
leagues.name
) AS countryleague,
CONCAT(
EVENTS.team1_name,
" vs ",
EVENTS.team2_name
) AS game,
CONCAT(
eo1.value,
" <a href=\"#\" class=\"add-bet\" data-id=\"",
eo1.id,
"\"><i class=\"fa fa-plus\"></i></a>"
) AS home,
CONCAT(
eo2.value,
" <a href=\"#\" class=\"add-bet\" data-id=\"",
eo2.id,
"\"><i class=\"fa fa-plus\"></i></a>"
) AS draw,
CONCAT(
eo3.value,
" <a href=\"#\" class=\"add-bet\" data-id=\"",
eo3.id,
"\"><i class=\"fa fa-plus\"></i></a>"
) AS away,
CONCAT(
eo4.value,
" <a href=\"#\" class=\"add-bet\" data-id=\"",
eo4.id,
"\"><i class=\"fa fa-plus\"></i></a>"
) AS over,
CONCAT(
eo5.value,
" <a href=\"#\" class=\"add-bet\" data-id=\"",
eo5.id,
"\"><i class=\"fa fa-plus\"></i></a>"
) AS under,
CONCAT(
"<a href=\"#\" class=\"expand-all btn\" data-id=\"",
EVENTS.id,
"\"><i class=\"fa fa-plus\"></i> Expand all odds</a>"
) AS expand,
`leagues`.`major`,
`leagues`.`name` AS `league`
FROM
`events`
INNER JOIN
`countries` ON `events`.`country_id` = `countries`.`id` AND `countries`.`id` IN(1)
INNER JOIN
`leagues` ON `events`.`league_id` = `leagues`.`id` AND `leagues`.`id` IN(1,
50)
LEFT JOIN
`event_odds` AS `eo1` ON `events`.`id` = `eo1`.`event_id` AND `eo1`.`market_id` = 3 AND `eo1`.`market_value_id` = 1 AND `eo1`.`bookmaker_id` IN(1,
2,
24) AND `eo1`.`value` = `eo1`.`best_odd`
LEFT JOIN
`event_odds` AS `eo2` ON `events`.`id` = `eo2`.`event_id` AND `eo2`.`market_id` = 3 AND `eo2`.`market_value_id` = 2 AND `eo2`.`bookmaker_id` IN(1,
2,
24) AND `eo2`.`value` = `eo2`.`best_odd`
LEFT JOIN
`event_odds` AS `eo3` ON `events`.`id` = `eo3`.`event_id` AND `eo3`.`market_id` = 3 AND `eo3`.`market_value_id` = 3 AND `eo3`.`bookmaker_id` IN(1,
2,
24) AND `eo3`.`value` = `eo3`.`best_odd`
LEFT JOIN
`event_odds` AS `eo4` ON `events`.`id` = `eo4`.`event_id` AND `eo4`.`market_id` = 4 AND `eo4`.`market_value_id` = 49 AND `eo4`.`bookmaker_id` IN(1,
2,
24) AND `eo4`.`value` = `eo4`.`best_odd`
LEFT JOIN
`event_odds` AS `eo5` ON `events`.`id` = `eo5`.`event_id` AND `eo5`.`market_id` = 4 AND `eo5`.`market_value_id` = 50 AND `eo5`.`bookmaker_id` IN(1,
2,
24) AND `eo5`.`value` = `eo5`.`best_odd`
WHERE
`events`.`sport_id` IN(1) AND `events`.`event_datetime` > 1507204934
GROUP BY
`events`.`id`
ORDER BY
`leagues`.`major` DESC,
`leagues`.`name` ASC,
`events`.`event_datetime` ASC
LIMIT 50 OFFSET 0
我正在以雄辩的方式建造它:
$query = Event_model::join('countries', function($q) use ($enabled_country_ids) {
$q->on('events.country_id', '=', 'countries.id')
->whereIn('countries.id', $enabled_country_ids);
})
->join('leagues', function($q) use ($enabled_league_ids) {
$q->on('events.league_id', '=', 'leagues.id')
->whereIn('leagues.id', $enabled_league_ids);
})
->leftJoin('event_odds AS eo1', function($q) use($win_market, $home_market_value, $enabled_bookmaker_ids) {
$q->on('events.id', '=', 'eo1.event_id')
->where('eo1.market_id', '=', $win_market->id)
->where('eo1.market_value_id', '=', $home_market_value->id)
->whereIn('eo1.bookmaker_id', $enabled_bookmaker_ids)
->on('eo1.value', '=', 'eo1.best_odd');
})
->leftJoin('event_odds AS eo2', function($q) use($win_market, $draw_market_value, $enabled_bookmaker_ids) {
$q->on('events.id', '=', 'eo2.event_id')
->where('eo2.market_id', '=', $win_market->id)
->where('eo2.market_value_id', '=', $draw_market_value->id)
->whereIn('eo2.bookmaker_id', $enabled_bookmaker_ids)
->on('eo2.value', '=', 'eo2.best_odd');
})
->leftJoin('event_odds AS eo3', function($q) use($win_market, $away_market_value, $enabled_bookmaker_ids) {
$q->on('events.id', '=', 'eo3.event_id')
->where('eo3.market_id', '=', $win_market->id)
->where('eo3.market_value_id', '=', $away_market_value->id)
->whereIn('eo3.bookmaker_id', $enabled_bookmaker_ids)
->on('eo3.value', '=', 'eo3.best_odd');
})
->leftJoin('event_odds AS eo4', function($q) use($ou_market, $over_market_value, $enabled_bookmaker_ids) {
$q->on('events.id', '=', 'eo4.event_id')
->where('eo4.market_id', '=', $ou_market->id)
->where('eo4.market_value_id', '=', $over_market_value->id)
->whereIn('eo4.bookmaker_id', $enabled_bookmaker_ids)
->on('eo4.value', '=', 'eo4.best_odd');
})
->leftJoin('event_odds AS eo5', function($q) use($ou_market, $under_market_value, $enabled_bookmaker_ids) {
$q->on('events.id', '=', 'eo5.event_id')
->where('eo5.market_id', '=', $ou_market->id)
->where('eo5.market_value_id', '=', $under_market_value->id)
->whereIn('eo5.bookmaker_id', $enabled_bookmaker_ids)
->on('eo5.value', '=', 'eo5.best_odd');
})
->whereIn('events.sport_id', $enabled_sports_ids)
->where('events.event_datetime', '>', time())
->groupBy('events.id')
->select([
'events.id',
DB::raw('FROM_UNIXTIME(events.event_datetime, "%a %D %b %H:%i") AS datetime'),
DB::raw('CONCAT(countries.name, " ", leagues.name) AS countryleague'),
DB::raw('CONCAT(events.team1_name, " vs ", events.team2_name) AS game'),
DB::raw('CONCAT(eo1.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo1.id, "\"><i class=\"fa fa-plus\"></i></a>") AS home'),
DB::raw('CONCAT(eo2.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo2.id, "\"><i class=\"fa fa-plus\"></i></a>") AS draw'),
DB::raw('CONCAT(eo3.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo3.id, "\"><i class=\"fa fa-plus\"></i></a>") AS away'),
DB::raw('CONCAT(eo4.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo4.id, "\"><i class=\"fa fa-plus\"></i></a>") AS over'),
DB::raw('CONCAT(eo5.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo5.id, "\"><i class=\"fa fa-plus\"></i></a>") AS under'),
DB::raw('CONCAT("<a href=\"#\" class=\"expand-all btn\" data-id=\"", events.id, "\"><i class=\"fa fa-plus\"></i> Expand all odds</a>") AS expand'),
'leagues.major',
'leagues.name AS league'
]);
if(!empty($order) && !$sort) {
foreach($order as $order_info) {
$query->orderBy($columns[$order_info['column']], $order_info['dir']);
}
}
if($sort) {
list($col, $order) = explode('|', $sort);
$query->orderBy($col, $order);
if($col=='countries.name') {
$query->orderBy('events.event_datetime');
}
}
if($league_id) {
$query->where('events.league_id', '=', $league_id);
}
if($search['value']!='') {
$query->where(function($q) use ($search) {
$q->orWhere('events.team1_name', 'LIKE', "%".$search['value']."%")
->orWhere('events.team2_name', 'LIKE', "%".$search['value']."%")
->orWhere('leagues.name', 'LIKE', "%".$search['value']."%");
});
}
或者我可以将它构建为一个大字符串,而不是:
$query = '
SELECT
`events`.`id`,
FROM_UNIXTIME(events.event_datetime, "%a %D %b %H:%i") AS datetime,
CONCAT(countries.name, " ", leagues.name) AS countryleague,
CONCAT(events.team1_name, " vs ", events.team2_name) AS game,
CONCAT(eo1.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo1.id, "\"><i class=\"fa fa-plus\"></i></a>") AS home,
CONCAT(eo2.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo2.id, "\"><i class=\"fa fa-plus\"></i></a>") AS draw,
CONCAT(eo3.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo3.id, "\"><i class=\"fa fa-plus\"></i></a>") AS away,
CONCAT(eo4.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo4.id, "\"><i class=\"fa fa-plus\"></i></a>") AS over,
CONCAT(eo5.value, " <a href=\"#\" class=\"add-bet\" data-id=\"", eo5.id, "\"><i class=\"fa fa-plus\"></i></a>") AS under,
CONCAT("<a href=\"#\" class=\"expand-all btn\" data-id=\"", events.id, "\"><i class=\"fa fa-plus\"></i> Expand all odds</a>") AS expand,
`leagues`.`major`,
`leagues`.`name` AS `league`
FROM `events`
JOIN `countries`
ON `events`.`country_id` = `countries`.`id`
AND `countries`.`id` IN ('.implode(',', $enabled_country_ids).')
JOIN `leagues`
ON `events`.`league_id` = `leagues`.`id`
AND `leagues`.`id` IN ('.implode(',', $enabled_league_ids).')
LEFT JOIN `event_odds` AS `eo1`
ON `events`.`id` = `eo1`.`event_id`
AND `eo1`.`market_id` = '.$win_market->id.'
AND `eo1`.`market_value_id` = '.$home_market_value->id.'
AND `eo1`.`bookmaker_id` IN('.implode(',', $enabled_bookmaker_ids).')
AND `eo1`.`value` = `eo1`.`best_odd`
LEFT JOIN `event_odds` AS `eo2`
ON `events`.`id` = `eo2`.`event_id`
AND `eo2`.`market_id` = '.$win_market->id.'
AND `eo2`.`market_value_id` = '.$draw_market_value->id.'
AND `eo2`.`bookmaker_id` IN('.implode(',', $enabled_bookmaker_ids).')
AND `eo2`.`value` = `eo2`.`best_odd`
LEFT JOIN `event_odds` AS `eo3`
ON `events`.`id` = `eo3`.`event_id`
AND `eo3`.`market_id` = '.$win_market->id.'
AND `eo3`.`market_value_id` = '.$away_market_value->id.'
AND `eo3`.`bookmaker_id` IN('.implode(',', $enabled_bookmaker_ids).')
AND `eo3`.`value` = `eo3`.`best_odd`
LEFT JOIN `event_odds` AS `eo4`
ON `events`.`id` = `eo4`.`event_id`
AND `eo4`.`market_id` = '.$ou_market->id.'
AND `eo4`.`market_value_id` = '.$over_market_value->id.'
AND `eo4`.`bookmaker_id` IN('.implode(',', $enabled_bookmaker_ids).')
AND `eo4`.`value` = `eo4`.`best_odd`
LEFT JOIN `event_odds` AS `eo5`
ON `events`.`id` = `eo5`.`event_id`
AND `eo5`.`market_id` = '.$ou_market->id.'
AND `eo5`.`market_value_id` = '.$under_market_value->id.'
AND `eo5`.`bookmaker_id` IN('.implode(',', $enabled_bookmaker_ids).')
AND `eo5`.`value` = `eo5`.`best_odd`
WHERE `events`.`sport_id` IN('.implode(',', $enabled_sports_ids).')
AND `events`.`event_datetime` > '.time().'
GROUP BY `events`.`id`
ORDER BY
`leagues`.`major` DESC,
`leagues`.`name` ASC,
`events`.`event_datetime` ASC
LIMIT 50 OFFSET 0';
如果我使用eloquent来构建查询而不执行它需要1.899秒,而如果我使用字符串方法需要0.006秒。
我更愿意使用雄辩,但我无法像这样表现出色,我能做些什么来加速用雄辩的方式构建查询?