Improve performance of the game history query by a lot.

Fixes #7988

I have no idea why this helps anything at all, since my understanding has always been that inner joins vs a big where clause are essentially two different ways of accomplishing the same thing, but changing the two inner joins to a where clause improves query performance from 6.3 to 0.012 seconds (when running the query from the website VM). As best I can tell from the explain plans, the inner joins are somehow confusing the query optimizer to use the game_content_info table as the starting point of the query instead of the game_info table, but why it's doing that or why it has such a large impact remains a mystery.
This commit is contained in:
pentarctagon 2023-10-26 19:03:06 -05:00 committed by Pentarctagon
parent 6b9a7627b9
commit c8b12c0902

View file

@ -152,9 +152,25 @@ std::unique_ptr<simple_wml::document> dbconn::get_game_history(int player_id, in
" then SUBSTRING(game.INSTANCE_VERSION, 1, 4) "
" else 'trunk' "
" end as VERSION "
"from "+db_game_info_table_+" game "
"inner join "+db_game_player_info_table_+" player "
" on exists "
"from "+db_game_player_info_table_+" player , "+db_game_content_info_table_+" scenario , "+db_game_content_info_table_+" era , "+db_game_info_table_+" game ";
// using a left join when searching by modification won't exclude anything
game_history_query += search_content_type == 2 && !search_content.empty() ? "inner join " : "left join ";
game_history_query += db_game_content_info_table_+" mods "
" on mods.TYPE = 'modification' "
" and mods.INSTANCE_UUID = game.INSTANCE_UUID "
" and mods.GAME_ID = game.GAME_ID ";
// modification id optional parameter
if(search_content_type == 2)
{
if(!search_content.empty())
{
game_history_query += "and mods.ID like ? ";
utils::to_sql_wildcards(search_content, false);
params.emplace_back(search_content);
}
}
"where exists "
" ( "
" select 1 "
" from "+db_game_player_info_table_+" player1 "
@ -171,8 +187,14 @@ std::unique_ptr<simple_wml::document> dbconn::get_game_history(int player_id, in
" and game.INSTANCE_UUID = player.INSTANCE_UUID "
" and game.GAME_ID = player.GAME_ID "
" and player.USER_ID != -1 "
" and game.END_TIME is not NULL ";
" and game.END_TIME is not NULL "
" and scenario.TYPE = 'scenario' "
" and scenario.INSTANCE_UUID = game.INSTANCE_UUID "
" and scenario.GAME_ID = game.GAME_ID "
" and era.TYPE = 'era' "
" and era.INSTANCE_UUID = game.INSTANCE_UUID "
" and era.GAME_ID = game.GAME_ID ";
// game name optional paramenter
if(!search_game_name.empty())
{
game_history_query += "and game.GAME_NAME like ? ";
@ -181,10 +203,7 @@ std::unique_ptr<simple_wml::document> dbconn::get_game_history(int player_id, in
params.emplace_back(search_game_name);
}
game_history_query += "inner join "+db_game_content_info_table_+" scenario "
" on scenario.TYPE = 'scenario' "
" and scenario.INSTANCE_UUID = game.INSTANCE_UUID "
" and scenario.GAME_ID = game.GAME_ID ";
// scenario id optional parameter
if(search_content_type == 0)
{
if(!search_content.empty())
@ -196,10 +215,7 @@ std::unique_ptr<simple_wml::document> dbconn::get_game_history(int player_id, in
}
}
game_history_query += "inner join "+db_game_content_info_table_+" era "
" on era.TYPE = 'era' "
" and era.INSTANCE_UUID = game.INSTANCE_UUID "
" and era.GAME_ID = game.GAME_ID ";
// era id optional parameter
if(search_content_type == 1)
{
if(!search_content.empty())
@ -211,23 +227,6 @@ std::unique_ptr<simple_wml::document> dbconn::get_game_history(int player_id, in
}
}
// using a left join when searching by modification won't exclude anything
game_history_query += search_content_type == 2 && !search_content.empty() ? "inner join " : "left join ";
game_history_query += db_game_content_info_table_+" mods "
" on mods.TYPE = 'modification' "
" and mods.INSTANCE_UUID = game.INSTANCE_UUID "
" and mods.GAME_ID = game.GAME_ID ";
if(search_content_type == 2)
{
if(!search_content.empty())
{
game_history_query += "and mods.ID like ? ";
utils::to_sql_wildcards(search_content, false);
params.emplace_back(search_content);
}
}
game_history_query += "group by game.INSTANCE_UUID, game.GAME_ID "
"order by game.START_TIME desc "
"limit 11 offset ? ";