Daniel Israel
05-27-2009, 09:46 PM
Hi, I was hoping someone here would have a good idea to help me optimize a query. I have a database that's keeping track of a users proficiency in a test. The user asks to take a test, then the test is constructed of a random sample (and order) of questions. There are 2 tables, tracking, and instance.
The tracking table keeps track of users test instance and score
The instance table tracks the test instances (questions and responses)
They look like this:
CREATE TABLE `ert_tracking` (
`id` int(11) NOT NULL auto_increment,
`user_id` varchar(50) NOT NULL,
`completed` tinyint(1) NOT NULL default '0',
`data` int(11) NOT NULL,
`instance` varchar(50) NOT NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `UserIndex` (`user_id`)
);
CREATE TABLE IF NOT EXISTS `ert_test_instance` (
`id` int(11) NOT NULL auto_increment,
`instance` varchar(50) NOT NULL,
`question` int(11) NOT NULL,
`answer` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `instance` (`instance`)
);
So what I need to do is to get a list of all the questions that have been presented to a given user. So I use a subquery to get the test instances from that user and query the instance table. It looks like this:
SELECT * FROM ert_test_instance WHERE instance IN (SELECT instance FROM ert_tracking WHERE user_id='<SOME ID>')
This seems to be taking a long time. So I did an explain... the ert_tracking table has like 2000 rows and the row count in the EXPLAIN (for the subquery) is 16, so that's dandy, but the primary query says it has no key to use (although I clearly defined an instance key and reference it) so it's going through all several thousand of the instance rows...
I know I can do a join (which works great), but the next step is to delete all the instance items for a particular user, so a join won't help me on the delete (or will it?)
Any ideas on this one? Thanks.
The tracking table keeps track of users test instance and score
The instance table tracks the test instances (questions and responses)
They look like this:
CREATE TABLE `ert_tracking` (
`id` int(11) NOT NULL auto_increment,
`user_id` varchar(50) NOT NULL,
`completed` tinyint(1) NOT NULL default '0',
`data` int(11) NOT NULL,
`instance` varchar(50) NOT NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `UserIndex` (`user_id`)
);
CREATE TABLE IF NOT EXISTS `ert_test_instance` (
`id` int(11) NOT NULL auto_increment,
`instance` varchar(50) NOT NULL,
`question` int(11) NOT NULL,
`answer` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `instance` (`instance`)
);
So what I need to do is to get a list of all the questions that have been presented to a given user. So I use a subquery to get the test instances from that user and query the instance table. It looks like this:
SELECT * FROM ert_test_instance WHERE instance IN (SELECT instance FROM ert_tracking WHERE user_id='<SOME ID>')
This seems to be taking a long time. So I did an explain... the ert_tracking table has like 2000 rows and the row count in the EXPLAIN (for the subquery) is 16, so that's dandy, but the primary query says it has no key to use (although I clearly defined an instance key and reference it) so it's going through all several thousand of the instance rows...
I know I can do a join (which works great), but the next step is to delete all the instance items for a particular user, so a join won't help me on the delete (or will it?)
Any ideas on this one? Thanks.