#mysql #database
#mysql #База данных
Вопрос:
допустим, у меня есть следующие объекты:
Site:
idSite,
name
and other static data.
Test:
idTest
idSite
name
and other static data.
Site Version:
idSiteVersion,
idSite
name of version
Test Result:
ןdTestResult
idSiteVersion,
idTest,
timeEnded
для каждого сайта есть список тестов, которые зарегистрированы для него.
теперь я хочу знать для каждого из них site version
последние testresults
данные, сгруппированные по idTest
. а также для тех, кто не тестировался, с нулевым значением. (b)
Я внедрил БД для этого.
но у меня возникли проблемы с получением запроса, который я перечислил (b), это занимает много времени.
Я подумываю о его переделке. любые советы помогут
новый будет состоять из таблицы, LATEST
которая будет действовать как кэш,
поэтому я буду использовать триггеры при вставке, чтобы обновить нужную строку,
и выберу из нее.
это верно?
должен ли я переделать это?
запрос:
select `tr1`.`id` AS `id`,
`dsv`.`idSite_id` AS `idSite`,
`tr1`.`idSiteVersion_id` AS `idSiteVersion`,
`tr1`.`idTest_id` AS `idTest`,
`tr1`.`result` AS `result`,
`tr1`.`timeStarted` AS `timeStarted`,
from
`dash`.`testresult` `tr1`
join `dash`.`siteversion` `dsv` on `dsv`.`id` = `tr1`.`idSiteVersion_id`
join `dash`.`test` `dtest` on `dtest`.`id` = `tr1`.`idTest_id`
where `dtest`.`ignored` = 0 and `tr1`.`timeEnd` =
( select max(`tr2`.`timeEnd`) from `dash`.`testresult` `tr2`
where
((`tr2`.`idTest_id` = `tr1`.`idTest_id`) and
(`tr2`.`idSiteVersion_id` = `tr1`.`idSiteVersion_id`) and
(`tr2`.`timeEnd` is not null)))
Комментарии:
1. Удалите idSite из TestResult, потому что вы можете получить его через тест.
2. Было бы полезно, если бы вы опубликовали свой запрос. Если у вас медленный запрос, как правило, первое, что нужно сделать, это профилировать его, чтобы убедиться, что он использует правильные индексы и т.д.
3. @Jason, просто
show profile
?4. @shevski покажите нам запрос. Если это занимает значительное количество времени, это, скорее всего, может быть оптимизировано без необходимости реструктуризации.
5. @MatthewCox это занимает больше нескольких секунд, я опубликую это, когда буду работать
Ответ №1:
Попробуйте это так:
SELECT
tr1.id AS id,
dsv.idSite_id AS idSite,
tr1.idSiteVersion_id AS idSiteVersion,
tr1.idTest_id AS idTest,
tr1.result AS result,
tr1.timeStarted AS timeStarted,
FROM
dash.testresult AS tr1
NATURAL JOIN (
SELECT idTest_id, idSiteVersion_id, MAX(timeEnd) AS timeEnd
FROM dash.testresult
WHERE timeEnd IS NOT NULL
GROUP BY idTest_id, idSiteVersion_id
) AS tr2
JOIN dash.siteversion AS dsv
ON dsv.id = tr1.idSiteVersion_id
JOIN dash.test AS dtest
ON dtest.id = tr1.idTest_id AND dtest.ignored = 0
Кроме того, вы определенно хотите создать индекс на dash.testresult (idTest_id, idSiteVersion_id, timeEnd)
, если у вас его еще нет.
Комментарии:
1.
AND
подразумевается, что конец запроса будетWHERE
?2. Вы тоже можете использовать
WHERE dtest.ignored = 0
, но я сделал это частью условия объединения, так как мне так показалось приятнее. Здесь это не должно иметь никакого значения в любом случае.3. этот запрос действительно сократил время выполнения