|
|
|
| Допустим мне надо вывести данные из трёх таблиц, возьмем просмотр фотографии, надо вытащить данные о пользователе, данные фотографии и данные категории которой принадлежит фотография. Известно только 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;
Данный запрос проработает быстрее чем три отдельных запроса и может быть можно его еще как то оптимизировать? | |
|
|
|
|
|
|
|
для: Jakeryf
(02.02.2009 в 04:30)
| | id's во всех трех таблицах - первичные ключи?
Я бы убрал повтор во 2 - 5 строках,
переписал бы в форму LEFT JOIN
убрал бы LIMIT 1
Но по большому счету, это всё косметика. Сильно быстрее не будет. | |
|
|
|
|
|
|
|
для: Trianon
(02.02.2009 в 09:18)
| | left join работает медленнее обычного join, а без limit 1 будет еще медленнее | |
|
|
|
|
|
|
|
для: mechanic
(02.02.2009 в 11:07)
| | В приведенном запросе?
Почему?
Benchmark и explain подтверждают? | |
|
|
|
|
|
|
|
для: Trianon
(02.02.2009 в 11:10)
| | я тут слегка потестил.
Как и предполагал, LIMIT 1 никак на скорость исполнения запроса не повлиял. Так что мусор.
добавление LEFT запрос либо не изменило либо ускорило на какие-то крохи.
Практически с LEFT операцию выполнить проще, чем без оного, а по логике оная не позволяет случайно потерять данные, если в дочерних таблицах нет строк.
счетчик бенчмарка в районе 1e6...1e8
Впрочем, тестовые таблицы были относительно небольшими.
Эксплэйн, как и ожидалось, показывает применение первичных ключей при обращении ко всем трем таблицам и просмотр ровно одной строки.
Повторюсь, различие во времени настолько незначительно (сотые доли секунды при сотне миллионов повторов) что сравнивать имеет смысл лишь эстетическую, так сказать, сторону. | |
|
|
|
|
|
|
|
для: Trianon
(02.02.2009 в 12:01)
| | хорошо, а если нам надо выбрать не одну запись, а 100, меняем tb1.id = ".$id." на tb1.id >".$id.", а LIMIT 1 на LIMIT 100 ?
id первичные ключи всо всех трёх таблицах | |
|
|
|
|
|
|
|
для: Jakeryf
(02.02.2009 в 12:39)
| | какие 100 ?
И почему 100? | |
|
|
|
|
|
|
|
для: Trianon
(02.02.2009 в 12:43)
| | чтобы выбрать только 100 записей из бд
не нравится 100 можно использовать любое другое число =)
просто я все запросы пишу в таком стиле без использования JOIN'ов так таковых, и хочу узнать сильно ли это сказывается на быстродействие | |
|
|
|
|
|
|
|
для: Jakeryf
(02.02.2009 в 13:33)
| | только сто каких именно записей?
Вы же понимаете. что если в таблице (в таблице кстати, а не в БД) записей тысяча, а Вы хотите взять просто сто, то запрос становится неопределенным?
Вместо того, чтоб думать, как сказывается запрос на быстродействии, лучше бы писали их так, чтоб они были понятнее сформулированы.
А для проверки быстродействия есть EXPLAIN и BENCHMARK. | |
|
|
|
|
|
|
|
для: 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 записей. | |
|
|
|
|
|
|
|
для: Axxil
(02.02.2009 в 13:51)
| | Ага. Пасиб. Добавлю еще чуток.
Применение LIMIT не имеет никакого смысла, если не задан ORDER BY. | |
|
|
|
|
|
|
|
для: Jakeryf
(02.02.2009 в 04:30)
| | спасибо за разъяснения | |
|
|
|