Оптимизация запроса, что быстрее.

Dima85

Новичок
Есть таблица users в ней 15 столбцов.
Задача найти нужного человека по Login и вывести его имя - 'Username'
Первый вариант:
Код:
  $rows = mysql_query("SELECT `Username`, `login` FROM `users` WHERE `login`='$login'");
  $this= mysql_fetch_assoc($rows);
Второй:
Код:
  $rows = mysql_query("SELECT * FROM `users` WHERE `login`='$login'");
  $this= mysql_fetch_assoc($rows);
Оба варианта работают. Первый насколько я понимаю будит быстрее работать и менее грузить хостинг? Или второй вариант идентичен первому и не стоит парится по этому поводу?
 

WMix

герр M:)ller
Партнер клуба
Оптимизация запроса, что быстрее.
первый может и быстрее, данных меньше, но врятли тебя интересуют такие глупости, хотяб потому что этот вопрос возник. считай что равносильно, а вероятнее второй лучше!
 

peon

Lok'tar ogar
выполни запрос в phpmyadmin и глянь
про нагрузку на хостинг, бред. твои запросы погоды не делают
в плане читабельности, один запрос явно указывает какие данные нужны и все
 

fixxxer

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

DiMA

php.spb.ru
Команда форума
В SQLite замена SELECT * на перечень определенных полей по минимому всегда играет роль.
 

fixxxer

К.О.
Партнер клуба
Может, у него php4 :)

Кстати, если хочется, то можно - любым косвенным способом, который не соптимизируется на этапе компиляции в "$this". ${'th'.'is'} = 1 или $a = 'this'; $$a = 1;
 

daemon_master

Новичок
Код:
SELECT `Username`, `login` FROM `users` WHERE `login`='$login'
- этот вариант быстрее, т.к. не происходит выбора всех данных. Если создать еще индекс (login, username) тогда этот запрос станет еще быстрее, т.к. для того, чтобы достать все необходимые данные не нужно будет лезть за ними дальше индекса. При наличии индекса запрос с выбором всех полей становится ощутимо медленнее на таблицах, в которых несколько миллионов строк.

Если же у вас в таблице не будет больших объёмов данных, блобов и кол-во столбцов небольшое, то разницы особой вы не почувствуете.
 

daemon_master

Новичок
У тебя происходит два этапа:
1. Поиск данных в индексе. (Будет проходит в двух случаях)
2. Доступ к самим данным. Если табличка большая, то чаще всего эти данные лежат на диске (если в оперативку еще все влазит, то еще можно с этим жить)
3. Чтение всех данных для нужной строчки.

По факту, нам нужно только одно поле. Если оно есть в индексе, было вместе с фильтрующим аргументом, то нам достаточно было только первого пункта для решения поставленной задачи. Опять же повторюсь, если все влазит в оперативку, то ок. Но лучше, чтобы более сложный запрос занял время DB worker-а, нежели такой.

А да, чуть не забыл. В конечном счете выполнение этого запроса можно перенести в HandlerSocket, если все данные есть в индексе.
 

Redjik

Джедай-мастер
1. Поиск данных в индексе. (Будет проходит в двух случаях)
не понял про в двух случаях =(

поиск по индексу b-tree всегда имеет логарифмическую сложность... что по сути всегда выливается в ничтожное время поиска
2. Доступ к самим данным. Если табличка большая, то чаще всего эти данные лежат на диске (если в оперативку еще все влазит, то еще можно с этим жить)
3. Чтение всех данных для нужной строчки.
доступ к данным на HDD ограничен скоростью вращения шпенделя + чтение (скорость пропорциональна фрагментации)

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

А да, чуть не забыл. В конечном счете выполнение этого запроса можно перенести в HandlerSocket, если все данные есть в индексе.
ага и двойные ковычки еще заменить на одинарные

ЗЫ.
Но лучше, чтобы более сложный запрос занял время DB worker-а, нежели такой.
wat?
 

daemon_master

Новичок
не понял про в двух случаях =(
Про то, что эта операция будет использоваться и в запросе SELECT username и SELECT *

поиск по индексу b-tree всегда имеет логарифмическую сложность... что по сути всегда выливается в ничтожное время поиска
До тех пор, пока вы не имеете дела с архивами, поискам по ежедневным логам, пусть даже и структурированным, фин. операциям и т.д. Логарифмическая сложность - это очень хорошее упрощение.

доступ к данным на HDD ограничен скоростью вращения шпенделя + чтение (скорость пропорциональна фрагментации)
Как часты вы заглядываете в iotop на ваших приложениях?
Очень много затрат уходит, если мы говорим про HDD, на подгонку головки до блина + скорость чтения с ПЗУ заметно меньше, чем с ОЗУ.
У нас на продакшене мастер нода БД приложения в 120 Гб влазит в оперативку. Запросы с фронт-енда в БД отдаются менее 10мс (некоторые данные обязательно должны быть прочитаны всегда с мастера). Ранее, когда оперативки на ноде было меньше, мы часто лазили в io. Среднее время на запрос от БД было в районе 40мс.

короче по факту ты предлагаешь сделать своебразный хак, для хранения в памяти username через индексы - сомнительно это
Хаком это назвать сложно. DBA-щик при полном аудите БД уж очень много раз напишет в репорте об этом.

ага и двойные ковычки еще заменить на одинарные
Сарказм не очень

Я про то, что если ты можешь что-то оптимизировать без особых усилий, чтобы потом не искать эту проблему, лучше это сделать сразу.
 

Redjik

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

Хаком это назвать сложно. DBA-щик при полном аудите БД уж очень много раз напишет в репорте об этом.
ну значит гнать надо такорго DBA, ну или отправить читать High Perfomance Mysql, ибо если, что то нужно хранить в памяти, то мало того, что у MySQL есть несколько способов это сделать, так не факт, что это не стоит прокинуть в Redis/Memcache. А юзать индексы, для того, чтобы столбец был в памяти ... жесть какая

Тем более мы говорим о Логине - не архивах и т.п. ... ЛОГИНЕ, просто оперативка будет простаивать с ненужными данными, к которым обращение идет 0,1% от остальных
Преждевременная оптимизация не меньшее зло.

Я про то, что если ты можешь что-то оптимизировать без особых усилий, чтобы потом не искать эту проблему, лучше это сделать сразу.
А я про то, что mysqld не плодит воркеров
 

Redjik

Джедай-мастер
вы наверное и FK удаляете, чтобы скорости добавить... сталкивался с таким
 

daemon_master

Новичок
Откуда вы взяли 0.1%?
Редис и мемкеш - далеко не решение всех проблем. При большом количестве нод, частые запросы в редис и мемкеш, очень хорошо начинают сеть грузить.

А юзать индексы, для того, чтобы столбец был в памяти ... жесть какая
Топикстартер спросил что быстрее, я дал ответ что и как. К чему жесть? Если же вы ссылаетесь на книгу High Performance MySql, то и там такое можете найти.

Есть смысл продолжать разговор дальше? Лично я в нем продолжения не вижу.
 

Фанат

oncle terrible
Команда форума
При наличии индекса запрос с выбором всех полей становится ощутимо медленнее на таблицах, в которых несколько миллионов строк.
Два раза прочитал дискуссию, но так и не увидел обоснования этой глубокой мысли. Если что, я ее читаю как
ЕСЛИ есть индекс ТО скорость выдачи одной строки данных растет пропорционально росту количества строк в таблице

а вообще, последний вброс напомнил бессмертное
— Папа, почему если надкусишь яблоко, оно коричневеет?
— Дело в том, сынок, что при нарушении целостности клеточной оболочки содержащаяся в клетках заменимая аминокислота тирозин под воздействием фермента тирозиназы вступает с атмосферным кислородом в реакцию, продуктом которой является пигмент меланин.
— Папа... Ты с кем сейчас разговаривал?
 

Absinthe

жожо
Если выбор конкретных полей не покрыт индексом, то разницы особой нет.
 
Сверху