Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Оптимизирован ли запрос?
 
 автор: Jakeryf   (02.02.2009 в 04:30)   письмо автору
 
 

Допустим мне надо вывести данные из трёх таблиц, возьмем просмотр фотографии, надо вытащить данные о пользователе, данные фотографии и данные категории которой принадлежит фотография. Известно только id фотографии
SELECT
tb1.foto as foto,
tb1.id as id,
tb1.name as name,
tb1.foto as foto,
tb1.date_add as date_add,
tb2.name as cat_name,
tb3.login as user_login
FROM
alt_fotos as tb1,
alt_categs as tb2,
alt_users as tb3
WHERE

tb1.id = ".$id." AND
tb2.id = tb1.categ AND
tb3.id = tb1.user_id
LIMIT 1;

Данный запрос проработает быстрее чем три отдельных запроса и может быть можно его еще как то оптимизировать?

  Ответить  
 
 автор: Trianon   (02.02.2009 в 09:18)   письмо автору
 
   для: Jakeryf   (02.02.2009 в 04:30)
 

id's во всех трех таблицах - первичные ключи?
Я бы убрал повтор во 2 - 5 строках,
переписал бы в форму LEFT JOIN
убрал бы LIMIT 1

Но по большому счету, это всё косметика. Сильно быстрее не будет.

  Ответить  
 
 автор: mechanic   (02.02.2009 в 11:07)   письмо автору
 
   для: Trianon   (02.02.2009 в 09:18)
 

left join работает медленнее обычного join, а без limit 1 будет еще медленнее

  Ответить  
 
 автор: Trianon   (02.02.2009 в 11:10)   письмо автору
 
   для: mechanic   (02.02.2009 в 11:07)
 

В приведенном запросе?
Почему?
Benchmark и explain подтверждают?

  Ответить  
 
 автор: Trianon   (02.02.2009 в 12:01)   письмо автору
 
   для: Trianon   (02.02.2009 в 11:10)
 

я тут слегка потестил.
Как и предполагал, LIMIT 1 никак на скорость исполнения запроса не повлиял. Так что мусор.
добавление LEFT запрос либо не изменило либо ускорило на какие-то крохи.
Практически с LEFT операцию выполнить проще, чем без оного, а по логике оная не позволяет случайно потерять данные, если в дочерних таблицах нет строк.
счетчик бенчмарка в районе 1e6...1e8
Впрочем, тестовые таблицы были относительно небольшими.
Эксплэйн, как и ожидалось, показывает применение первичных ключей при обращении ко всем трем таблицам и просмотр ровно одной строки.

Повторюсь, различие во времени настолько незначительно (сотые доли секунды при сотне миллионов повторов) что сравнивать имеет смысл лишь эстетическую, так сказать, сторону.

  Ответить  
 
 автор: Jakeryf   (02.02.2009 в 12:39)   письмо автору
 
   для: Trianon   (02.02.2009 в 12:01)
 

хорошо, а если нам надо выбрать не одну запись, а 100, меняем tb1.id = ".$id." на tb1.id >".$id.", а LIMIT 1 на LIMIT 100 ?
id первичные ключи всо всех трёх таблицах

  Ответить  
 
 автор: Trianon   (02.02.2009 в 12:43)   письмо автору
 
   для: Jakeryf   (02.02.2009 в 12:39)
 

какие 100 ?
И почему 100?

  Ответить  
 
 автор: Jakeryf   (02.02.2009 в 13:33)   письмо автору
 
   для: Trianon   (02.02.2009 в 12:43)
 

чтобы выбрать только 100 записей из бд
не нравится 100 можно использовать любое другое число =)
просто я все запросы пишу в таком стиле без использования JOIN'ов так таковых, и хочу узнать сильно ли это сказывается на быстродействие

  Ответить  
 
 автор: Trianon   (02.02.2009 в 13:48)   письмо автору
 
   для: Jakeryf   (02.02.2009 в 13:33)
 

только сто каких именно записей?
Вы же понимаете. что если в таблице (в таблице кстати, а не в БД) записей тысяча, а Вы хотите взять просто сто, то запрос становится неопределенным?

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

А для проверки быстродействия есть EXPLAIN и BENCHMARK.

  Ответить  
 
 автор: Axxil   (02.02.2009 в 13:51)   письмо автору
 
   для: Trianon   (02.02.2009 в 12:01)
 

Добавлю чуток.

LIMIT - своеобразный аналог array_slice, он просто режет полный набор на порции.

Т.е.
select * from posts limit 100000,20

вопреки убеждению многих не берёт только 20 записей. Он берёт 100020 записей и отбрасывает первые 100000. Для оптимизации этого запроса лучше сделать выборку
select * from posts where post_id between 100000 and 100020


естественно post_id - уникальный ключ и физического удаления записей не происходит. При удалении их можно помечать флагом fl_deleted, например. В данном случае задействовано будет в запросе только 20 записей.

  Ответить  
 
 автор: Trianon   (02.02.2009 в 13:59)   письмо автору
 
   для: Axxil   (02.02.2009 в 13:51)
 

Ага. Пасиб. Добавлю еще чуток.
Применение LIMIT не имеет никакого смысла, если не задан ORDER BY.

  Ответить  
 
 автор: Jakeryf   (02.02.2009 в 14:27)   письмо автору
 
   для: Jakeryf   (02.02.2009 в 04:30)
 

спасибо за разъяснения

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования