В дополнение к рекомендации @Gordon Linoff, вы должны рассмотреть вопрос нормализации вашей таблицы, чтобы сделать SQL более эффективным. Используйте очень короткий код или int
для status_id
и сохраните уникальный список кодов состояния и описания в справочной таблице. Затем просто присоединитесь к таблице поиска в вашем SQL. См. статью для подробного объяснения нормализации.
Я также рекомендую изменить имя столбца или тип данных для столбца time
, поскольку это не имеет смысла. Какое значение времени требует 255 символов?
Если вас беспокоит производительность, то первое, на что вы должны обратить внимание, - это удалить ненужные байты, сортировки и фильтры из вашего запроса. Этот подход имеет дело с большинством проблем производительности. То, как вы присоединяетесь к столам, также важно. По мере увеличения объема и сложности данных настройка также становится все более сложной.
Знакомство EXPLAIN
поможет вашим усилиям. Обратитесь к ОБЪЯСНИТЕ документации для получения дополнительной информации.
-- Create your lookup table first
CREATE TABLE `material_status` (
`id` int(11) NOT NULL,
`status` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `material_status`
ADD PRIMARY KEY (`id`),
ALTER TABLE `material_status`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
-- Then create your user_material table
CREATE TABLE `user_material` (
`id` int(11) NOT NULL,
`user_course_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`material_id` int(11) NOT NULL,
`attempt` int(11) NOT NULL,
`another_attempt` tinyint(1) DEFAULT '0',
`status_id` int(11) DEFAULT NULL,
`complete` tinyint(1) DEFAULT NULL,
`percent` float DEFAULT '0',
`time` varchar(255) DEFAULT NULL,
`marking_time` varchar(255) DEFAULT NULL,
`marked_by` int(11) DEFAULT NULL,
`feedback` text,
`submitted_date` datetime DEFAULT NULL,
`marking_date` datetime DEFAULT NULL,
`created` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create your extra index here
CREATE INDEX ix-submitted_date ON user_material(submitted_date);
-- Add the status to the keys and constraints
ALTER TABLE `user_material`
ADD PRIMARY KEY (`id`),
ADD KEY `user_material-user` (`user_id`),
ADD KEY `user_material-material` (`material_id`),
ADD KEY `user_material-marking-user` (`marked_by`),
ADD KEY `user_course-user_material` (`user_course_id`),
ADD KEY `user_material-status` (`status_id`);
ALTER TABLE `user_material`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `user_material`
ADD CONSTRAINT `user_course-user_material` FOREIGN KEY (`user_course_id`) REFERENCES `user_course` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `user_material-marking-user` FOREIGN KEY (`marked_by`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `user_material-material` FOREIGN KEY (`material_id`) REFERENCES `material` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `user_material-user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `user_material-status` FOREIGN KEY (`status_id`) REFERENCES `material_status` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Теперь запросы будут выглядеть так:
SELECT
um.id,
um.user_course_id,
um.user_id,
um.material_id,
um.attempt,
um.another_attempt,
ms.status,
um.complete,
um.percent,
um.time,
um.marking_time,
um.marked_by,
um.feedback,
um.submitted_date,
um.marking_date,
um.created
FROM user_material um
INNER JOIN material_status ms on ms.id = um.status_id
WHERE ms.status = 'submitted';
SELECT
um.id,
um.user_course_id,
um.user_id,
um.material_id,
um.attempt,
um.another_attempt,
ms.status,
um.complete,
um.percent,
um.time,
um.marking_time,
um.marked_by,
um.feedback,
um.submitted_date,
um.marking_date,
um.created
FROM user_material um
INNER JOIN material_status ms on ms.id = um.status_id
ORDER BY um.submitted_date ASC;