Что хуже "Using Filesort" или "Using Temporary"?

Bermuda

Новичок
Что хуже "Using Filesort" или "Using Temporary"?

В мануале написано, что в первом случае базе придется еще один проход по таблице для сортировки, а во втором, что для получения результата будет создана временная таблица.
Собственно сабж.
Что тормознее?
На каком количестве данных появятся тормоза с "Using Filesort"?

Спасибо.
 

WP

^_^
Естественно Using Temporary намного тормознее.
> На каком количестве данных появятся тормоза с "Using Filesort"?
Вопрос некорректен.
 

fisher

накатила суть
>>Естественно Using Temporary намного тормознее
это неверно. правильного ответа в общем случае нет. временная таблица может быть очень легкой, и совсем не обязательно приведет к тормозам. более того, наличие filesort в эксплейне также совершенно необязательно приводит к тормозам - поскольку иногда он встречается и на довольно простых и быстрых запросах. а в худшем случае - да, тормоза оба. но по-моему, filesort опаснее - просто потому что с ростом чиста данных filesort будет иметь большее число дисковых операций, чем просто создание и последовательное чтение из временной таблицы.
 

Bermuda

Новичок
Автор оригинала: fisher
правильного ответа в общем случае нет.
Потому и пытаюсь разобраться, дабы не допускать ошибок при проектировании модели данных или по крайней мере провести частичную оптимизацию на этом этапе.
Тем не менее отвественность за создание временной таблице лежит на "движке" базы и на операционной системе. Т. е. при определенных условиях совсем не обязательно то, что таблица будет создана на жестком диске, она может быть создана в памяти. Таким образом напрашивается предположение, что при небольшом количестве данных создание временной таблицы не так страшно, как filesort. Однако с ростом количества записей генерируемая временная таблица может получаться достаточно большая для того, чтобы главным тормозом было создание файла на диске (+ возможная фрагментация).
Потому и стоит вопрос, различается ли эффект тормозов в зависимости от количества данных в случае с filesort и Using Temporary.
 

andry

Новичок
А у Вас что, есть два варианта одного запроса? Один на filesort, другой на Using Temporary?
в некоторых случаях нельзя избежать Using Temporary,например, при группировке не по ключю.
 

Bermuda

Новичок
andry
Да, есть несколько вариантов. Using Temporary практически всегда удается избежать при помощи подзапросов. Избежать Using Filesort немного труднее. Вот хочу выбрать из двух зол.
 

fisher

накатила суть
Однако с ростом количества записей генерируемая временная таблица может получаться достаточно большая для того, чтобы главным тормозом было создание файла на диске
при этом если есть filesort то операций будет ещё больше - возможно, сильно больше. фишка в том, что там совсем не "один проход по таблице для сортировки" , как вы написали.

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
там хитрецы документопейсатели сделали очень краткое описание модифицированного метода сортировки - там всего лишь "Sort the tuples by sort key value" но по сути именно тут весь гемор mergebuf и есть, и при большом количестве данных это далеко не одна операция. это из общих физических соображений - вообще, апельсинку или свету бы сюда ;)

-~{}~ 13.06.07 17:21:

Using Temporary практически всегда удается избежать при помощи подзапросов
ой, я боюсь это неправильная стратегия. и вообще, это как-то мне сомнительно. а оно реально ускоряет или просто не пишет using temporary?
 

andry

Новичок
Автор оригинала: Bermuda
andry
Да, есть несколько вариантов. Using Temporary практически всегда удается избежать при помощи подзапросов. Избежать Using Filesort немного труднее. Вот хочу выбрать из двух зол.
Я боюсь, что такие способы "избежать" окажутся еще более тормозными. Конечно, все зависит от конкретного случая.
 

Bermuda

Новичок
fisher
Просто не пишет. На большом количестве записей пока не проверял. Я не знаю как оно справляется. Видимо подзапрос как бы и является временной таблицей, к которой делается внеший запрос. Пишет ли оно это в файл я не знаю. По крайней мере в эксплэйне не не появляется, но есть стэк из нескольких запросов.
 

fisher

накатила суть
ясно. если запрос частый а writes мало может добавить/перестроить индекс?
P.S. я стараюсь ВООБЩЕ не использовать subqueries
 

Bermuda

Новичок
fisher
В основном Using Temporary появляется при LEFT JOIN.

Например мне нужно показать контент только активных пользователей (без бана) и отсортировать контент по дате

SELECT *
FROM content
WHERE iduser IN
(SELECT id FROM users WHERE flag_active = 1)
AND flag_active = 1
ORDER BY date DESC
Тут оно не делает временную таблицу, более того пользуется индексами


В более сложном случае требуется показать активный контент активных пользователей являющихся членами тех (активных) сообществ, в которых зарегистрирован текущий пользователь.

Или отсортировать список активных пользователей в зависимости от количества активного контента им принадлежащего
SELECT *
FROM users
LEFT JOIN
(
SELECT iduser, COUNT(*) as cnt
FROM content
WHERE flag_active = 1
GROUP BY iduser
) as tbl_cont
ON users.id = tbl_cont.iduser
WHERE flag_active = 1
ORDER BY cnt DESC
Тут вроде бы тоже получается избавиться от временной таблицы.

Запросы написал по памяти и упрощенно. Хочу понять как их оптимизировать.
Это "оптимизированные" запросы. Как сделать тоже самое без подзапросов думаю понятно, но вот как избавится от временной таблицы -- не совсем.

-~{}~ 13.06.07 15:38:

P.S. я стараюсь ВООБЩЕ не использовать subqueries
Я тоже стараюсь, но в редких случая очень трудно найти другое решение.
 

alpine

Новичок
Bermuda
Первый запрос легко можно переписать через INNER JOIN и попробовать поиграться с ним.

Во втором, как я понимаю, поскольку подзапрос находится в условии FROM, то им создается производная таблица(derived table aka unnamed view), тоесть временная таблица, причем даже при експлейне.
 

Bermuda

Новичок
alpine
Да, можно, но тогда если у пользователя пока еще нет контента, то он в список он не попадет, а вывести нужно всех.
Во втором очевидно, что результат оно должно куда-то сохранять, но тем не менее "Using Temporary" не пишет.

derived table это временная таблица?
 

alpine

Новичок
Bermuda
Да, можно, но тогда если у пользователя пока еще нет контента, то он в список он не попадет, а вывести нужно всех.
Да без проблем, перепиши через LEFT JOIN он даже быстрей.
http://dev.mysql.com/doc/refman/5.0/en/rewriting-subqueries.html
derived table это временная таблица?
угу
 

Bermuda

Новичок
Всем спасибо за разъяснения. Позже как вернсусь снова к запросам которые не могу разрулить -- вывалю их здесь.

Да, может кто подскажет, как избежать временной таблицы при запросе вида
SELECT *, COUNT(*) as cnt
FROM table
GROUP BY id
ORDER BY cnt
 

confguru

ExAdmin
Команда форума
Таких запросов и писать не нужно... судя по всему..
зачем тебе count в каждой строке и каждый раз.. :)
Сделай отдельную маленькую табличку где будут хранится count


Автор оригинала: Bermuda
Всем спасибо за разъяснения. Позже как вернсусь снова к запросам которые не могу разрулить -- вывалю их здесь.

Да, может кто подскажет, как избежать временной таблицы при запросе вида
SELECT *, COUNT(*) as cnt
FROM table
GROUP BY id
ORDER BY cnt
 

fisher

накатила суть
>> Сделай отдельную маленькую табличку где будут хранится count
+1
сортировка по вычисляемому полю на большом числе данных - это жесть
 
Сверху