20 мая 2013 г.

Наглядно сравнить профилинг двух и более запросов MySQL


В данном случае мне в общих записях запрашиваемой таблице нужны так же количество имеющихся упоминаний об этой записи по другим таблицам ... родилось как минимум два варианта решения ... то есть нужен профилинг что бы оценить цену запроса каждого и время обработки ... а сравнивать их штатным образом не удобно ...

Нашел информацию что результаты профилинга лежат так же в  INFORMATION_SCHEMA, что и родило сия пост, дабы из головы не вылетел в будущем ...

Примеры запросов приведены в общих чертах

/* Example query 1 */
select sql_no_cache * ... from users u
left join (select count(*) ...) s0 on s0.user_id = u.id
left join (select count(*) ...) s1 on s1.user_id = u.id
left join ( select count(*) ... inner join invites i on i.id = ...item_id  group by ...user_id) s2 on s2.user_id = u.id
where u.id in ( ... );

/* Example query 2 */
select sql_no_cache * ...
(select count(*) ... where user_id = u.id)count_1,
(select count(*) ... where user_id = u.id)count_2,
(select count(*) ... inner join invites i on i.id = ...item_id where ...)count_3
from users u
where u.id in ( ... );
Включаем профилинг и последовательно выполняем каждый из них, просматриваем
set profiling=1;
/* ... to execute our queries ... */
set profiling=0;
show profile for query 1;
show profile for query 2;
Увы, штатного средства сравнения двух профилингов не нашел. В процессе поиска даже наткнулся на гуевенькую прожку для этих целей но у неё два минуса: платная и под винду.

Почитав про профилинг и места его сохранений, родилось что то типа вт такой костылины:


SELECT STATE, FORMAT(DURATION1,6), FORMAT(DURATION2,6), FORMAT(DURATION1-DURATION2,6) DiffTime
FROM (
SELECT p.STATE, ifnull(sum(p1.DURATION),0) DURATION1, ifnull(sum(p2.DURATION),0) DURATION2
FROM INFORMATION_SCHEMA.PROFILING p
LEFT JOIN INFORMATION_SCHEMA.PROFILING p1 on p1.STATE = p.STATE and p1.QUERY_ID = 1
LEFT JOIN INFORMATION_SCHEMA.PROFILING p2 on p2.STATE = p.STATE and p2.QUERY_ID = 2
GROUP BY p.STATE ORDER BY p.SEQ)t
UNION ALL
SELECT "total", FORMAT(sum(DURATION1),6), FORMAT(sum(DURATION2),6), FORMAT(sum(DURATION1)-sum(DURATION2),6)
FROM (
SELECT p.STATE, ifnull(sum(p1.DURATION),0) DURATION1, ifnull(sum(p2.DURATION),0) DURATION2
FROM INFORMATION_SCHEMA.PROFILING p
LEFT JOIN INFORMATION_SCHEMA.PROFILING p1 on p1.STATE = p.STATE and p1.QUERY_ID = 1
LEFT JOIN INFORMATION_SCHEMA.PROFILING p2 on p2.STATE = p.STATE and p2.QUERY_ID = 2
GROUP BY p.STATE ORDER BY p.SEQ)t
;

меня смущает что я не смог найти что то более красивое и элегантное ... хотя может быть фиговски искал =)

пс. по сути можно в процедуру завернуть ... но моей задаче это не требуется ...

Комментариев нет:

Отправить комментарий