$q = "SELECT count(f.user_id) AS count FROM #prefix#follows AS f ";
$q .= "WHERE f.follower_id = :userid AND f.network=:network ";
is very slow to run on my db, taking e.g. 10 mins (though in my case it doesn't use much cpu).
This query is on the tu_follows table also.
I'm thinking that tu_follows needs one or maybe two more indexes:
ALTER TABLE `tu_follows` ADD INDEX ( `network`, `active` );
and maybe also
ALTER TABLE `tu_follows` ADD INDEX ( `network` );
though I think the first of the two is the most useful.
I added these today, and early indications are that this has fixed my slowdown issue.
I don't believe there should be any harm in adding these indexes even if they don't fix your particular issue. It might take a bit of time to add them if you have a lot of data.
Gina, what do you think?
[I guess the more indexes you add, the longer the write time... but the faster the query time]
Also-- should the query in countTotalFriends query be checking for 'active = 1' too?
--
You received this message because you are subscribed to the Google
Groups "ThinkUp App" group.
http://groups.google.com/group/thinkupapp?hl=en
Find out more about ThinkUp:
http://thinkupapp.com
> There is also a quirk in MySQL where indexes on two columns can also act as
> an index on a single column (this only works in order from left to right (or
> first to last, whichever you prefer)).
I didn't realize that!
In that case we can be smarter about adding indexes to tu_follows.
There is already a unique key: (user_id,follower_id,network)
So sounds like we should redefine this as (network, user_id, follower_id).
I'll give that a try in my installation.
--
> You can also use the "EXPLAIN SELECT" SQL command to see what indexes your
> queries are using.
That's really useful. It appears that both my problematic query:
SELECT count(f.user_id) AS count FROM temp_tu_follows AS f WHERE f.follower_id = 123456 AND f.network='twitter';
and Zuhaib's:
SELECT user_id AS followee_id, follower_id FROM temp_tu_follows AS f WHERE network='twitter' AND active = 1 ORDER BY f.last_seen ASC LIMIT 1;
were not using indexes.
For Zuhaib's query, indexing 'last_seen' produced dramatic speedups on my database.
I think all our queries will constrain on 'network', so perhaps 'network' should be listed first in all the indexes for speed. At any rate, the
following set of indexes works better for me. But, I haven't looked over all the tu_follows queries (which is what we would want to do to generate an optimal set of indexes).
CREATE TABLE tu_follows (
user_id bigint(11) NOT NULL,
follower_id bigint(11) NOT NULL,
last_seen timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
active int(11) NOT NULL DEFAULT '1',
network varchar(20) NOT NULL DEFAULT 'twitter',
debug_api_call varchar(255) NOT NULL,
UNIQUE KEY user_id (network, follower_id, user_id),
KEY last_seen (network, last_seen),
KEY active (network, active)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--Amy
Looks like these index updates are worth doing, then--thanks Amy. I've
created an issue:
https://github.com/ginatrapani/ThinkUp/issues/issue/517
At some point I'd like to set up a general SQL optimization test suite
which fills the tables with a few million rows and then runs all the
DAO queries against them a few hundred times and times the results so
we can systematically adjust queries and indexes and surface problems
like this. Anyone have any experience with this sort of thing?