isedeasy Posted January 19, 2011 Share Posted January 19, 2011 I have the following query which works just fine until I have a few hundred rows in one of the joined tables, then it takes over 30 sec to load the page. How can I optimise this query? I have certain columns indexed. SELECT a.id, COUNT(DISTINCT b.id) AS table1no, COUNT(DISTINCT c.id) AS table2no, COUNT(DISTINCT d.id) AS table3no, COUNT(DISTINCT e.id) AS table4no FROM table a LEFT JOIN table1 AS b ON b.user = a.id LEFT JOIN table2 AS c ON c.user = a.id AND c.deleted = 0 LEFT JOIN table3 AS d ON d.user = a.id AND d.status != 2 AND d.stage = 5 LEFT JOIN table4 AS e ON e.user = a.id AND e.status != 2 AND e.stage = 5 WHERE a.id = $id Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/ Share on other sites More sharing options...
requinix Posted January 20, 2011 Share Posted January 20, 2011 It seems like you're trying to do 5 different queries at the same time. What if you split them apart? Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1162265 Share on other sites More sharing options...
mikosiko Posted January 20, 2011 Share Posted January 20, 2011 @isedeasy To get better help - What is the EXPLAIN result for that sentence? - Post Tables structure and Index definitions... complement with number of rows in each table Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1162271 Share on other sites More sharing options...
fenway Posted January 22, 2011 Share Posted January 22, 2011 You know, there's a sticky that describes exactly what information we'll need to help you. Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1163732 Share on other sites More sharing options...
kickstart Posted January 23, 2011 Share Posted January 23, 2011 Hi Couple of thing not really to do with optimisation. Looks like you need a group by clause. Assuming b.id, etc, are primary keys and so unique there is no need to use distinct. You don't need the AS when aliasing the table names Efficiency wise it is going to come down to whether b.user, etc, are set up foreign keys. All the best Keith Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1163921 Share on other sites More sharing options...
isedeasy Posted January 26, 2011 Author Share Posted January 26, 2011 Thanks for all the replies so far, they have all been very helpful. I have been looking into foreign keys and I have completely redone all my keys/indexes to use foreign keys where applicable. The problem I have at the moment is my comment system, I have 3 different types of items that users can comment on so I have a column for the items id and a column for the type of item (because the id's are auto increment). therefore all the comments are in one table. Should I use a separate table for each type of item users can comment on? that way I can use foreign keys to link the row with the items ID or should I keep it as it is and just have an index consisting of item combined with id? tableA - id tableB - id tableC - id CommentsTable - item (either tableA, tableB, or tableC), id Hope that makes sense Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1165658 Share on other sites More sharing options...
mikosiko Posted January 26, 2011 Share Posted January 26, 2011 In my first reply to you I wrote: - Post Tables structure and Index definitions... complement with number of rows in each table ... no information provided... now.... I have 3 different types of items that users can comment based on that and your mention of tables (A, B, C) make me suspicious about if your data modeling is correct or not.... for a better answer post your tables structure and explain a little what you are doing.... Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1165678 Share on other sites More sharing options...
isedeasy Posted January 26, 2011 Author Share Posted January 26, 2011 That's my point I want the correct structure. Shall I have a separate comment table for each of the three types or one comment table with a column for the type? Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1165714 Share on other sites More sharing options...
mikosiko Posted January 27, 2011 Share Posted January 27, 2011 post the structures of your tables A,B y C Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1165794 Share on other sites More sharing options...
isedeasy Posted January 27, 2011 Author Share Posted January 27, 2011 CREATE TABLE `comments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` int(6) NOT NULL, `item` int(6) NOT NULL, `type` int(1) NOT NULL, PRIMARY KEY (`id`), KEY `user` (`user`), CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `item1` ( `id` int(6) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `item2` ( `id` int(6) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `item3` ( `id` int(6) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 I'm not at home now so will this watered down version do? I have it set up so that 1 in the comments.type column refers to item1, 2 in the comments.type column refurs to item2 etc So would be best for each item to have its own comments table or is there a way to use foreign keys for comments.item to reference the id of the items? Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1165934 Share on other sites More sharing options...
isedeasy Posted February 4, 2011 Author Share Posted February 4, 2011 Does anyone have an answer to my last question? "Shall I have a separate comment table for each of the three types or one comment table with a column for the type?" Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1169803 Share on other sites More sharing options...
fenway Posted February 13, 2011 Share Posted February 13, 2011 It's always simpler to have a shared table. Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1173576 Share on other sites More sharing options...
isedeasy Posted February 15, 2011 Author Share Posted February 15, 2011 It's always simpler to have a shared table. Ok thank you. How should I go about keys for this table? CREATE TABLE `comments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` int(6) NOT NULL, `item` int(6) NOT NULL, `type` int(1) NOT NULL, PRIMARY KEY (`id`), KEY `user` (`user`), CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 Is there away to use a foriegn key for the`item` column as it can be joined with different tables? Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1174586 Share on other sites More sharing options...
fenway Posted February 17, 2011 Share Posted February 17, 2011 Is there away to use a foriegn key for the`item` column as it can be joined with different tables? Nope. If you really want that, you'll need a "parent" table, and then subsequent child tables. Quote Link to comment https://forums.phpfreaks.com/topic/225022-optimise-query/#findComment-1175745 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.