Search code examples
mysqlgroup-bycountquery-performance

Mysql 3 tables, multiple counts grouped by, but gets stuck


I'm running with some troubles on a query. I'm trying to retrieve some data of a big database where 3 tables are involved.

These tables contain data about adds where, in a backend website, the administrator can manage which local adds he wants to be displayed, position and etc... These are organized in 3 tables, 1 of them, contains all the data that are relevant to adds info (Name, date of avaliability, date of expiration, etc...). Then, there's another 2 tables which contain some extra info, but just about views, or clicks.

So I have only 15 adds, that have multiple clicks and multiple views. Each click and view table, register a new row for every click. So, when a click is registered, it will add a new row where addid_views is a register(click), and addid is addid from adds_table. So for instance, add (1) will have 2 views and 2 clicks while add (2) will have 1 view and 1 click.

My idea is to get for each add, how many clicks and views had in total.

I have 3 tables like these:

         adds_table           adds_clicks_table        adds_views_table
    +-------+-----------+   +-------------+------+     +-------------+------+  
    | addid | name      |   | addid_click |addid |     | addid_views |addid |
    +-------+-----------+   +-------------+------+     +-------------+------+
    | 1     | add_name1 |   | 1           | 1    |     | 1           | 1    |
    +-------+-----------+   +-------------+------+     +-------------+------+
    | 2     | add_name2 |   | 2           | 2    |     | 2           | 1    |
    +-------+-----------+
    | 3     | add_name3 |   | 3           | 1    |     | 3           | 2    |
    +-------+-----------+   +-------------+------+     +-------------+------+


CREATE TABLE `bwm_adds` (
  `addid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  ...
  PRIMARY KEY (`addid`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

CREATE TABLE `bwm_adds_clicks` (
  `add_clickid` int(19) NOT NULL AUTO_INCREMENT,
  `addid` int(11) NOT NULL,
  ...
  PRIMARY KEY (`add_clickid`)
) ENGINE=InnoDB AUTO_INCREMENT=3374 DEFAULT CHARSET=utf8


CREATE TABLE `bwm_adds_views` (
  `add_viewsid` int(19) NOT NULL AUTO_INCREMENT,
  `addid` int(11) NOT NULL,
  ...
  PRIMARY KEY (`add_viewsid`)
) ENGINE=InnoDB AUTO_INCREMENT=2078738 DEFAULT CHARSET=utf8

The result would be a single table where I retrieved, per each add (addid), how many clicks and how many views it had.

I need to get all a query where I get something like this:

+-------+---------+-----------+
| addid | clicks  | views     |
+-------+---------+-----------+
| 1     | 123123  | 235457568 |
+-------+---------+-----------+
| 2     | 5124123 | 435345234 |
+-------+---------+-----------+
| 3     | 123541  | 453563623 |
+-------+---------+-----------+

I tried to execute a query but it get's stuck and loading for undefined time... I 'm pretty sure that my query is failing cause if I remove one of the counts, displays some data very fast.

SELECT a.addid, COUNT(ac.addid_clicks) as 'clicks', COUNT(av.addid_views) as 'views'
        FROM `adds_table` a 
        LEFT JOIN `adds_clicks_table` ac ON a.addid = ac.addid_click
        LEFT JOIN `adds_views_table` av ON ac.addid_click = av.addid_views
                GROUP BY a.addid

Mysql gets loading all the time, any idea to help know what I'm missing?

By the way, I found this post where treats almost the same problem I have, you can see I have the query very similar to the first answer, but I get the Loading message all the time. No errors, just Loading.

Edit: I missplaced the numbers and got confused. Now the tables are fixed and I added some explanation about it.

Edit2: I updated the post with SHOW CREATE TABLES DEFINITIONS.

Edit3: Is there any way to optimise this query? It seems it retrieves the result I want but the mysql database cancels the query because it gets more than 30 seconds to execute.

SELECT a.addid,
       (SELECT COUNT(addid) FROM add_clicks where addid =  a.addid) as clicks,
       (SELECT COUNT(addid) FROM add_views  where addid =  a.addid) as views
    FROM adds a ORDER BY a.addid;

Solution

  • I ended with a solution to my problem. The table I was trying to reach was too big cause of the bad engineered database, where in adds_views_table, for each view, a new row would be added. Ending with almost 3 millions of rows and with a table that weights almost the 35% of the entire database (326MB).

    When phpmyadmin tried to execute a query, loaded for ever and never showed a result because a timeout limit applied to mysql. Changing this value would help but wasn't viable to retrieve that data and display it on a website (that implies the website or data wouldn't load until the query its executed).

    That problem was fixed thanks to creating an index of addid in adds_table. Also, the query it's faster if subquery's are used for some reason. The query ended like this:

    SELECT a.addid,
    (SELECT COUNT(addid) FROM adds_clicks_table WHERE addid = a.addid) AS 'clicks',(SELECT COUNT(addid) FROM adds_views_table WHERE addid = a.addid) AS 'views'
    FROM adds_table a
    ORDER BY a.addid;
    

    Thanks to @Rick James who posted a similar query and I ended modifying it to get the data I needed

    forgive my horrible english