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

О! Я не сдох, не спился, не ужрался ягой. Дела у меня хорошо. Вращение придавал я вашим негативным отзывам обо мне. Короче, я живее всех живых и специально этой статьёй попытаюсь вам объяснить, как можно улучшить ваш букс, хайп, игру, любого рода самопальный проект и заставить его работать реще… Как? Читай.Такс. На моём горбу сейчас работает один проектец. И я не занимался оптимизацией 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 расписывать не имею желания. вот вам линк. Читаем (это хабр если чё). и обращаем внимание на запись в логи. если ты самоуверенный тип, знаешь что косяков и дыр уже не допускаешь – отрубай логирование. правда если тебя ломанут через дырочку, ты уже не узнаешь как именно, но зато ты был самоуверенным)))))

0

Понравилась статья? Поделись в соц. сетях:

Похожие новости

Комментарии

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

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

    Про дб – написано по делу.
    По 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 не ахти…

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

    0
  2. А Что есть еще люди которые пишут на mysql_*
    Вроде уже большинство хостов обновили пхп, да и ПДО гораздо удобнее и безопаснее обычного mysql_*

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

    По поводу mysql_real_escape_string , так вот она нихера не защищает от инъекций, смысла от нее толком и нету! Как и сказали выше, регулярки лучше!

    0
  3. Статья стара как мир.
    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. Затрата ресурсов таже самая а эффект лучше

    0
  4. андрей, с новым годом. сразу ответ
    0. статью написал сам хотя с хабра кое чё выдернул и что проверил и в чём реально убедился (что имеется результат итд)
    1. пассивное соединение лучший вариант.
    2. согласенн. в принципе nginx аналогично
    3. хоть 300 хоть 3 поля – лучше перечислить. при запросе со * мускул выберет все и потом уже вернет названия полей и уже следом даст выборку по ним
    4. есть логика. но имхо имеется смысл просто передавать всегда числовые данные. а текстовые у нас по сути идут в тот же чат, при реге и авторизации
    5. вот тут не шарю. будем пробовать
    6. и далее будем пробовать. ты же знаешь, что с настройкой сервереа я не силён да и голову лишний раз не заморачиваю) каждый должен заниматься своим делом)

    0
  5. Цитата: Alex
    Alex

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

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

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

    Чем щас занят в какую тематику ударился?

    0
  6. "…Я не спился и не сдох…", о блин, да всем насрать 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, то проблем с нагрузкой у вас впринципе быть не должно с вашими проектами и задачами!

    Все, всем пока 🙂 Зайду сюда снова через год 🙂

    0
  7. руфус брат ну блеа. как я чё нить напишу – ты сразу объявляешься. я уверен, что тебя тянет мой энтузиазм и потенциал. как бы ты не хуесосил меня в ответ, так онои есть. всё просто: мы с тобой в одном дерьме крутимся. был бы ты выше – ты б хер сюда заходил. та же тема и у меня) а пиской помериться дело святое) просто мериться надо в той плоскости, в которой писька оппонента и находится)

    0
  8. Alex,
    угу вы с Руфусом как два сапога пара, один появился, у другого как буд-то прога с парсингом с SFB – тинь Леха пост сделал и тут Руфус ))))
    ей богу

    0

Добавить комментарий

Авторизация
*
*
Регистрация
*
*
*
Генерация пароля