Skip to content
Advertisement

Optimising query with multiple selects as columns

I have a query I made:

 SELECT DISTINCT player_1 AS player, 
                (SELECT COUNT(*) FROM results WHERE player_1=player OR player_2=player) AS since_start_matches, 
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=0) AS since_start_ht_0,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=1) AS since_start_ht_1,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=2) AS since_start_ht_2,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=3) AS since_start_ht_3,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=4) AS since_start_ht_4,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals>=5) AS since_start_ht_5_plus
FROM results ORDER BY player

The results table has 25000 entries and it takes around 7 seconds to do this query, which is far too long. The query is incredibly inefficient as each column I’m creating is searching again on the same table but with different conditions.

I tried indexing the columns of interest in my where clause. This knocks off a couple of seconds. But it’s still too slow.

What is the best approach to handle this kind of query?

I’m using MariaDB 10.2

Advertisement

Answer

Unpivot the data then aggregation:

 SELECT player, 
        COUNT(*) AS since_start_matches, 
        SUM(ht_total_goals=0) AS since_start_ht_0,
        SUM(ht_total_goals=1) AS since_start_ht_1,
        SUM(ht_total_goals=2) AS since_start_ht_2,
        SUM(ht_total_goals=3) AS since_start_ht_3,
        SUM(ht_total_goals=4) AS since_start_ht_4,
        SUM( ht_total_goals>=5) AS since_start_ht_5_plus
FROM ((SELECT player_1 as player, ht_total_goals
       FROM results
      ) UNION ALL
      (SELECT player_2 as player, ht_total_goals
       FROM results
      )
     ) p
GROUP BY player
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement