Сайт поддержки администраторов САР, у нас вы можете скачать скрипты буксов, ферм и т.д, а также обсудить все это на форуме

Глючит проект?

Глючит проект?
Такс. На моём горбу сейчас работает один проектец. И я не занимался оптимизацией SQL запросов, не грузил себе голову настройкой и т.д. до тех пор пока он не запустился. Но с его запуском я забыл обо всей лабуде и вот когда начались первые фризы - пришло время немножко позаниматься. Сейчас попытаюсь вам объяснить чем можно ускорить работу сайта:

Немножко олдскульной банальщины:
mysql_connect

Убираем все mysql_close() и все mysql_connect. Оставляем первый коннект.

Больше банальщины:
mysqli_*

Процедурный стиль. Если юзаешь ООП - забудь о mysql, представь это ночным кошмаром. mysqli работает быстрее mysql и чуть чуть (крапаль) быстрее PDO. НО в ПДО простые инъекции отсеиваются автоматом, однако, если ты передаёшь все данные в числовом формате - гораздо быстрее их отсеивать intval() или лучше (int)$a. Текстовые поля стоит фильтровать. Можно поиграться с htmlentities (при желании).

Ещё немножко гипертупизма. str_replace/str_ireplace - не очень хорошо. Однако, то же можно сказать о echo и print. Если echo можно вызвать как функцию, то print нам позволяет играться с and. На самом деле это не критично, на это можно закрыть глаза.

Теперь о том, что реально поможет снизить нагрузку на железо:

1. require_once забыли. require и желательно вначале кода, если подключаемый файл не имеет исполняющего кода (например просто забитый дефолтом массив или константы).

2. SELECT * - нет слов. Все поля вытянули и перечислили через запятую, выигрыш существенный.

3. Таблицы или куча полей? На самом деле мускул рассчитан на то и другое. Хочешь - создай кучу полей, хочешь создай кучу таблиц. Стоит помнить, что при обращении к таблице мускул создаёт минимум 3 файла. На HDD это заметно, на SSD не очень заметно, поэтому хранить таблицу с рефами отдельно от общей таблицы юзеров ГЛУПО. Гораздо проще юзать index хотя бы.

4. index ёпть, это ваш помощник, запрос вида:
SELECT `col1`,`col2` FROM `table` WHERE `col3`='123'

В таблице table имеющей, допустим, лям строк будет перебирать ВСЕ СТРОКИ. Но стоит добавить index на col3 - ситуация изменится.

5. Рефсистемы:

Как предлагал dmk - если я авторизован - скрипт берёт мой id и перебирает таблицу referals и вытягивает всех, кто привязан к моему id (пусть в примере это будет поле ref_id).
SELECT `login`,`id` FROM `referals` WHERE `ref_id`='мойид';
//по результатам этого запроса берём инфу из users
SELECT `bla`,`bla`..... from `users` where `id`=result

Чёрт возьми, что нам мешает добавить одно числовое поле, допустим int(5) (5 число знаков - если рассчитываешь на большее - меняй) и поставить ему index?

select `bla`,`bla`... from `users` where `ref_id`='мойид'

Таким образом задействуешь одну таблицу.

6. InnoDB или MyISAM?

Банальные правила: InnoDB - отличный варик для динамических таблиц. Дело в том, что запросы вида:
UPDATE `table`

И вида:
INSERT INTO `table`

ЛОЧАТ таблицу table если она имеет тип MyISAM! А когда она лочится - с неё чтение становится невозможным - отсюда и глюки при чтении и соответственно в работе скрипта. Но есть и дёготь в этом дерьме: InnoDB не лочится при обновлении, НО чтение с неё происходит довольно медленнее.

ПОЭТОМУ СМОТРИМ ПУНКТЫ ВЫШЕ:

касаемо рефсистемы если каждое действие рефереру чё нить даёт и этих действий много - юзаем две таблицы (неоспоримо): например просмотр ссылок. таблица с рефами пусть будет myisam! users однозначно innodb

если реферер затрагивается например при пополнении или при депозите (хайп) наилучшим вариантом буедт также оставить users в формате innodb и всю реф структуру вязать на partner_id которому мы даём index

7. ...escape_string ЛЮБАЯ РЕГУЛЯРКА РАБОТАЕТ БЫСТРЕЕ ЧЕМ ЭТА ЛАЖА! помним об этом! лучше лишний раз через функцию прогнать чем этой хернёй защищаться. в текущем рынке хайпов, буксов, игр и прочей белиберды в основном используются числовые значения (intval в помощь). текстовые юзаются при реге и авторизации. ну ещё восстановлении и то FILTER_VALIDATE вам в помощь.

8. условия

if(a==b){
  if(c==d){
    if(e==f){

ЗАБУДЬТЕ ПРО ЭТУ ГРЯЗЬ!

если запрос шлёте аяксом или json то проверяйте ответ. задайте констату например 'ok'. Если ответ не ok то выводите алерт с ответом! не забудьте закрыть display_errors! и в таком случае условие будет вида


if(a!=b) exit('a not b');
if(c!=d) exit('c not d');
if(e!=f) exit('e not f');


Ну вот бывают ситуации и сложно с jquery! таких ребят тут много. никто вас не осуждает. ЛУЧШЕ ВСЕГО ЮЗАТЬ elseif


if(a!=b){ print 'a not b'; }
elseif(c!=d){ print 'c not d'; }
elseif(e!=f){ print 'e not f'; }
else{
//some do mother fucker blyat!
}


с условиями ясно.

9. Циклы грёбаные

Не буду объяснять почему (окей гугл юзайте), просто дам сразу вам по приоритету операторы:

1 место for
2 место foreach
3 место while

допусти вы берёте строки с users


//процедурка для непрошаренных
$SQL=mysql_query("SELECT `qqwq`.... FROM `users`");

//лучший вариант
for($i=1;$i<=mysql_num_rows($SQL);$i++){
$row=mysql_fetch_assoc($SQL);
}


самый суко быстрый вариант. мерил разными. любимый while курит в сторонке. foreach не ахти...

касаемо цикла в цикле:

for(i=1;i<=1000;i++){
  for(q=1;q<=10;q++){
//do some blyat
}
}

всё это херня! есть траблы? пиши в комменты (если юзаешь цикл в цикле) и дядька лёшка тебе подскажет, как это сделать шустрее. и сразу ответ на вопрос где такое может быть?

Такое строят обычно без опыта юзеры, либо не сильно заморачивающиеся. пресуще это для таблицы допустим с личкой. там будут значения "от", "кому", "дата сообщения", "стаус прочитан или нет". как бы вот челу надо вывести список уникальных диалогов - можно поюзать оператор, можно измудриться с from==id or to==id. по сути диалог - это общение между двумя пользователями. но это несложно если просто вывести по дате последнего сообщения, но иной раз нужно как бы вывести статус сообщения. в принципе идея по последнему сообщению своеобразна, но кто-то хочет и со статусом выпендриться (раньше я так выпендривался). вот тут то и идёт цикл в цикле и дополнительные условия в цикле.

Короче с SQL если будут мысли пишите. мой запал кончился на этом стакане вискаря. к сожалению, большущих стаканов у меня нет, и каждый новый стакан вынуждает меня переключиться в сторону другой области...поэтому перезарядившись, я пинаю вас в сторону nginx. почему именно он? потому что почти все VPS/VDS юзают его.

Для того, чтобы он думал резвее - нам нужно:
идём в панели управления в файловый менеджер. идём в корень. ищем путь /etc/nginx/nginx.conf

в нём:

worker_processes 18;


гуглим или заведомо знаем скок ядер наш процессор на сервере имеет и число ставим равным этому.

worker_connections 4000;

максимальное кол-во клиентов на коннект. лупим также 4к

ну и я советую врубить gzip в этом же файле


gzip on;  //включён
gzip_min_length 1024; //мин длина ответа для компрессии
gzip_proxied expired no-cache no-store private auth; //для каких запросов выёёпываемся
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml text/html; //форматы
gzip_disable "msie6"; //для юза в ие
gzip_comp_level 5; //степень сжатия (советую 5. сами экспериментируйте)



всё по nginx расписывать не имею желания. вот вам линк. Читаем (это хабр если чё). и обращаем внимание на запись в логи. если ты самоуверенный тип, знаешь что косяков и дыр уже не допускаешь - отрубай логирование. правда если тебя ломанут через дырочку, ты уже не узнаешь как именно, но зато ты был самоуверенным)))))


Рубрика: Информация » Программирование   |   Автор: Alex   |   Просмотры: 20941
Комментариев: 92
Публикаций: 0
ICQ: 471590730
  Автор: reklamawmb   |   Группа: Модераторы   |   Дата: 27 декабря 2015  
Alex, ты не спился еще? странно.
это все сарказм.

Давно тебя видно не было
Комментариев: 67
Публикаций: 0
ICQ: --
  Автор: Misha   |   Группа: Помощник администратора   |   Дата: 27 декабря 2015  
В основном советы не стоят того, чтоб их читать.
Они слишком очевидны для одной половины аудитории и в то же время, другая половина их прочитает, но не поймёт.

Далее насчёт оптимизаций

Про дб - написано по делу.
По php большинство пунктов - сомнительные
Цитата: Alex
7. ...escape_string ЛЮБАЯ РЕГУЛЯРКА РАБОТАЕТ БЫСТРЕЕ ЧЕМ ЭТА ЛАЖА! помним об этом! лучше лишний раз через функцию прогнать чем этой хернёй защищаться. в текущем рынке хайпов, буксов, игр и прочей белиберды в основном используются числовые значения (intval в помощь). текстовые юзаются при реге и авторизации. ну ещё восстановлении и то FILTER_VALIDATE вам в помощь.


Спорный вопрос. escape_string просто посылает запрос к мускулу для этой операции. Но иногда лучше использовать его(например сообщения в чатик)

Цитата: Alex
8. условия

if(a==b){
  if(c==d){
    if(e==f){

ЗАБУДЬТЕ ПРО ЭТУ ГРЯЗЬ!

если запрос шлёте аяксом или json то проверяйте ответ. задайте констату например 'ok'. Если ответ не ok то выводите алерт с ответом! не забудьте закрыть display_errors! и в таком случае условие будет вида


if(a!=b) exit('a not b');
if(c!=d) exit('c not d');
if(e!=f) exit('e not f');


Ну вот бывают ситуации и сложно с jquery! таких ребят тут много. никто вас не осуждает. ЛУЧШЕ ВСЕГО ЮЗАТЬ elseif


if(a!=b){ print 'a not b'; }
elseif(c!=d){ print 'c not d'; }
elseif(e!=f){ print 'e not f'; }
else{
//some do mother fucker blyat!
}


с условиями ясно.


Тут не про условия писать надо было, а про то что избегайте вложенного кода - его трудно читать. Используйте флаги, объединяйте некоторые условия или же ваш код потом сложно будет разобрать(а главное задебажить. Помню у велика в скрипте из-за этого накрутка при заказе рекламы проходила)

Цитата: Alex
9. Циклы грёбаные

Не буду объяснять почему (окей гугл юзайте), просто дам сразу вам по приоритету операторы:

1 место for
2 место foreach
3 место while

допусти вы берёте строки с users


//процедурка для непрошаренных
$SQL=mysql_query("SELECT `qqwq`.... FROM `users`");

//лучший вариант
for($i=1;$i<=mysql_num_rows($SQL);$i++){
$row=mysql_fetch_assoc($SQL);
}


самый суко быстрый вариант. мерил разными. любимый while курит в сторонке. foreach не ахти...


По поводу скорости алекс прав, экономия в процентах заметна, но в реальной задаче вы больше сэкономите, если оптимизируете запрос, перебираемый в цикле.
Комментариев: 123
Публикаций: 2
ICQ: 567777707
  Автор: Forceman   |   Группа: Пользователи   |   Дата: 27 декабря 2015  
хуйня. твой скилл за 5 лет так и не поднялся.
Комментариев: 330
Публикаций: 166
ICQ: 650073308
  Автор: Alex   |   Группа: Пользователи   |   Дата: 27 декабря 2015  
зацени свой и померимся мудила
Комментариев: 110
Публикаций: 20
ICQ: 6024242
  Автор: WmRush   |   Группа: Программисты   |   Дата: 28 декабря 2015  
А Что есть еще люди которые пишут на mysql_*
Вроде уже большинство хостов обновили пхп, да и ПДО гораздо удобнее и безопаснее обычного mysql_*

По поводу скорости циклов я реально не знал! Теперь взял на заметку!

По поводу mysql_real_escape_string , так вот она нихера не защищает от инъекций, смысла от нее толком и нету! Как и сказали выше, регулярки лучше!
Комментариев: 73
Публикаций: 18
ICQ: 634377420
  Автор: BeerMan   |   Группа: Пользователи   |   Дата: 29 декабря 2015  
mysql_real_escape_string уже устарело!
на счет условий так лучше использовать switch если есть возможность!
Комментариев: 218
Публикаций: 6
ICQ: 573235722
  Автор: VELIK505   |   Группа: Программисты   |   Дата: 30 декабря 2015  
Статья стара как мир.
1. одно соединение не есть хорошо! Недавно столкнулся с такой проблемой что mysql не успевает закрывать соединение если допустим у вас js post выполняеться каждый 10 секунд для 5000к онлайна и mysql ходит не локально будете получать 99ую нехватки исходящих портов и будет отстраиваться большая очередь back_log.
Решение увеличение port range
2. Если php крутиться на apache (что не есть хорошо) то используйте только постоянные соединения!
3. SELECT * - нет слов. Дело случая!
если нам надо получить 20 полей из 25ти то имеет место быть выбрать все нежели только определённые.
4. escape_string надо использовать велосипеды не надо мутить. Научитесь кешировать данные разницы по скорости не будет с прегматчем.
5. worker_processes лучше ставить в auto на последних версиях nginx.
6. worker_connections 4000; - это очень мало для нормального проекта типо профит центра того же. Мы даём максимальное кол-во соединения это 65536.
По мимо этого nginx даже не сможет принимать твои 4000 одновременных соединения. А максимум 2048! так они ограничены в ядре самой операционной системы.
Пофиксим sysctl:
net.core.somaxconn = 131072
и для очереди:
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
полуоткрытые убиваем (очень важные строчки)!!!:
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
Увеличиваем диапозон портов:
net.ipv4.ip_local_port_range = 1024 65535
не забываем рубить соединения (отстроить таймауты)дабы не получить сусфлуда и забития интернет канала:
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_time = 15
выставляйте приоритет nginx дабы при ддосе он не загинался и продолжал обрабатывать запросы:
worker_priority -2;
ЧЁ кто там говорит про mysql_real_escape_string что не защищает от инькций????
Вот в такой запрос воткни мне иньекцию:
SET `login`='". mysql_real_escape_string($login) ."' я тебе 10000р дам а если нет то ты мне 50000р.
Не хочу тебя расстраивать но она защищает на 100%. Конечно если ты ей обрабатываешь целочисленные данные обрамляя апострофами которые надо пускать через int и не обрамлять то она тебе не поможет.

gzip_types уже давно в таком виде не работает.
надо: gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
и уровень сжатия можно выставлять на 6. Затрата ресурсов таже самая а эффект лучше
Комментариев: 330
Публикаций: 166
ICQ: 650073308
  Автор: Alex   |   Группа: Пользователи   |   Дата: 01 января 2016  
андрей, с новым годом. сразу ответ
0. статью написал сам хотя с хабра кое чё выдернул и что проверил и в чём реально убедился (что имеется результат итд)
1. пассивное соединение лучший вариант.
2. согласенн. в принципе nginx аналогично
3. хоть 300 хоть 3 поля - лучше перечислить. при запросе со * мускул выберет все и потом уже вернет названия полей и уже следом даст выборку по ним
4. есть логика. но имхо имеется смысл просто передавать всегда числовые данные. а текстовые у нас по сути идут в тот же чат, при реге и авторизации
5. вот тут не шарю. будем пробовать
6. и далее будем пробовать. ты же знаешь, что с настройкой сервереа я не силён да и голову лишний раз не заморачиваю) каждый должен заниматься своим делом)
Комментариев: 29
Публикаций: 1
ICQ: 694917172
  Автор: trolleybus   |   Группа: Пользователи   |   Дата: 06 января 2016  
Для сео спринта пойдёт wink Рни уже давно глючат)))
Комментариев: 11
Публикаций: 0
ICQ: 584111388
  Автор: Admin24   |   Группа: V.I.P.   |   Дата: 13 февраля 2016  
Цитата: Alex
Alex


Alex Рад что жив здоров!

Жаль что новыми фитчами и алгоритмами нас не порадовал))

А так все верно говоришь чем быстрее работает тем совершеннее

Чем щас занят в какую тематику ударился?
Комментариев: 118
Публикаций: 2
ICQ: 819374
  Автор: Rufus   |   Группа: Программисты   |   Дата: 20 июля 2016  
"...Я не спился и не сдох...", о блин, да всем насрать xD
Все уже давно свои MVC написали и юзают успешно, а он пишет про mysql и оптимизацию запросов. 12 000000 записей в таблице, к таблице в секунду 15-100 запросов, и насрать, я даже чистить не буду, ибо кроме жстяка ничего не жрет...

mysql_close вообще убило, у тебя какая версия PHP? Помоему, эта финкция нужна в демоне и для постоянных соединений, во всех остальных случаях соединение закрывается автоматически после отрабатывания скрипта. Аля 2005 год у тебя еще!

Цитата: VELIK505
Статья стара как мир.

Статья как в ведро перднул!

Помоему, база весит 2 гига!



Представим, что мы выбираем по хешу пароля и у нас 5 паролей:

SELECT * FROM `pref_test_rows` WHERE `first_str` IN(
'fb670517410cae01bd324eef55c21651',
'673a9518d645803dd3dd6d8749390151',
'2099ba30befe3df80bb3efa5cd7d673a',
'2bc59b1655c836ccfec188407f6596c5',
'780d6b8e6e519d9d3ab2af6cffe83cdb'
)


Вот результат выполнения:



MySQL создан для хранения данных, а не для псевдоданных ввиде 10 строк в таблице. Если у вас руки растут не из жопы и вас в школе научили читать, а ваши знания немного больше чем mysql_close, то проблем с нагрузкой у вас впринципе быть не должно с вашими проектами и задачами!

Все, всем пока :) Зайду сюда снова через год :)
Комментариев: 330
Публикаций: 166
ICQ: 650073308
  Автор: Alex   |   Группа: Пользователи   |   Дата: 12 октября 2016  
руфус брат ну блеа. как я чё нить напишу - ты сразу объявляешься. я уверен, что тебя тянет мой энтузиазм и потенциал. как бы ты не хуесосил меня в ответ, так онои есть. всё просто: мы с тобой в одном дерьме крутимся. был бы ты выше - ты б хер сюда заходил. та же тема и у меня) а пиской помериться дело святое) просто мериться надо в той плоскости, в которой писька оппонента и находится)
Комментариев: 83
Публикаций: 3
ICQ: 423459532
  Автор: steam   |   Группа: Администраторы   |   Дата: 19 октября 2016  
Alex,
Он тут как обосрать надо, сам бы чего тогда накатал) Но ему не выгодно/лень/не хочет вообще связываться)
Комментариев: 163
Публикаций: 19
ICQ: 553069709
  Автор: ZKolyaNZ   |   Группа: Прогрaммисты   |   Дата: 06 января 2017  
Alex,
угу вы с Руфусом как два сапога пара, один появился, у другого как буд-то прога с парсингом с SFB - тинь Леха пост сделал и тут Руфус ))))
ей богу
Информация

Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.