Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 04.08.2012, 00:24
Аватар для Freakmeister
Аспирант
Отправить личное сообщение для Freakmeister Посмотреть профиль Найти все сообщения от Freakmeister
 
Регистрация: 15.01.2011
Сообщений: 61

Как работает mysql_query?
Снова встал ребром вопрос - как написать менее ресурсоёмко? Вчера мой сайт благополучно лёг после вживления в него нового куска кода. При 5 пользователях онлайн, проц был съеден моментально, а остатки оперативы в последующие 10 минут. Причиной этому послужил не код приведённый ниже - это уже моя попытка понять как можно написать менее ресурсоёмко.

Собссна, теоретический вопрос к знатокам - когда я делаю такой запрос с циклом, то что происходит при этом?
var $limit=10;
var $n=0;
$query = mysql_query("SELECT * FROM phpbb_posts ORDER BY post_id DESC", $db);
while ($n<$limit) {
	$row = mysql_fetch_array($query);
	$n++;
	//операции
}

Вариант А: mysql_query вытаскивает ВСЕ данные из phpbb_posts одним запросом, что очень ресурсоёмко, а потом mysql_fetch_array обрабатывает результат уже средствами php.
Вариант Б: mysql_query просто инициализирует связь с таблицей по выбранному фильтру, без вытаскивания значений, что не даёт особой нагрузки, а само вытаскивание уже происходит маленькими порциями при каждом обращении к mysql_fetch_array.
Вариант Ц: Ты баклан, почему ты не использовал LIMIT в SQL-запросе?

Для тех кто склоняется к последнему варианту, поясняю - в моём случае использовать LIMIT в SQL-запросе не получится. Потому что проверка прав пользователя происходит средствами php, и приходится сначала вытаскивать запись из БД, а потом уже проверять километровой функцией нужно выводить её на страницу или нет (грёбаный phpBB).

Последний раз редактировалось Freakmeister, 04.08.2012 в 00:27.
Ответить с цитированием
  #2 (permalink)  
Старый 04.08.2012, 00:58
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от Freakmeister
Потому что проверка прав пользователя происходит средствами php, и приходится сначала вытаскивать запись из БД, а потом уже проверять километровой функцией нужно выводить её на страницу или нет (грёбаный phpBB).
и что с чем вы сравниваете в PHP ? какие поля сравниваете и с какими? Любой вопрос я уверен что можно решить простыми запросами в БД
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #3 (permalink)  
Старый 04.08.2012, 02:32
Аватар для Freakmeister
Аспирант
Отправить личное сообщение для Freakmeister Посмотреть профиль Найти все сообщения от Freakmeister
 
Регистрация: 15.01.2011
Сообщений: 61

Не всё так просто. В phpBB привелегии пользователей храняться хрен найди в зашифрованном виде где. И доступ к форумам проверяется функцией, которая это дело расшифровывает: $auth->acl_get('f_read', $forum_id). Прямым доступом к БД тут никак не сделаешь. Картинка в тему:


Последний раз редактировалось Freakmeister, 04.08.2012 в 02:34.
Ответить с цитированием
  #4 (permalink)  
Старый 04.08.2012, 07:39
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Сообщение от Freakmeister
Вариант А: mysql_query вытаскивает ВСЕ данные из phpbb_posts одним запросом, что очень ресурсоёмко, а потом mysql_fetch_array обрабатывает результат уже средствами php.
Вариант Б: mysql_query просто инициализирует связь с таблицей по выбранному фильтру, без вытаскивания значений, что не даёт особой нагрузки, а само вытаскивание уже происходит маленькими порциями при каждом обращении к mysql_fetch_array.
Вариант Ц: Ты баклан, почему ты не использовал LIMIT в SQL-запросе?
Почему это вариант Б лучше — непонятно. От постоянного дёрганья базе лучше стать не может. А ещё данные, соответствующие выборке, надо где-то хранить. Как это делать с учётом того, что данных могут попросить много, а клиентов может быть ещё больше и всем надо быстро ответить — опять же, неясно. Ну и для идентификации нужен какой-нибудь идентификатор сессии, который придётся пересылать при каждом запросе, что увеличит как сетевую нагрузку, так и время работы БД, т.к. ей придется каждый раз искать данные, соответствующие сессии.
Ответить с цитированием
  #5 (permalink)  
Старый 04.08.2012, 11:02
Аватар для micscr
Профессор
Отправить личное сообщение для micscr Посмотреть профиль Найти все сообщения от micscr
 
Регистрация: 10.09.2009
Сообщений: 1,566

Одно из правил оптимизации - не делать SELECT *, а перечислять нужные поля.
Т.к. запрос то на mysql сервере сразу отработает и все данные где то будет хранить.
SELECT по всем постам это ужас.
Думай чтобы разбить этот алгоритм на множественное кол-во запросов. Сначала получаешь ограничения, а потом по этим ограничениям выбираешь данные.
Ответить с цитированием
  #6 (permalink)  
Старый 04.08.2012, 13:26
Аватар для Freakmeister
Аспирант
Отправить личное сообщение для Freakmeister Посмотреть профиль Найти все сообщения от Freakmeister
 
Регистрация: 15.01.2011
Сообщений: 61

Я изначально сделал так, после чего мой VDS-сервер благополучно лёг:

$i=$n=0;
$limit = 10;
while ($n<$limit) {
    $query = mysql_query("SELECT post_id, topic_id, forum_id, poster_id, post_time, post_subject FROM phpbb_posts ORDER BY post_id DESC LIMIT $i,1", $_P['db']);
    $row = mysql_fetch_array($query);

    if ($auth->acl_get('f_read', $row['forum_id'])) { // есть ли у юзера доступ

        //вытаскиваем имя пользователя и цвет его ника
        $query2 = mysql_query("SELECT username, user_colour FROM `phpbb_users` WHERE user_id=".$row['poster_id']." LIMIT 1", $_P['db']);
        $row2 = mysql_fetch_array($query2);

        //здесь идёт вывод через echo
         $n++;
    }
    $i++;
}

При обновлении страницы тут делается 20 маленьких запросов в лучшем случае. Короче, я сейчас думаю в сторону mysql_unbuffered_query.
Ответить с цитированием
  #7 (permalink)  
Старый 04.08.2012, 14:10
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от Freakmeister
$auth->acl_get
ну дык расковыряй что делает эта функция... и какая версия phpBB?
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #8 (permalink)  
Старый 05.08.2012, 15:26
Аватар для Freakmeister
Аспирант
Отправить личное сообщение для Freakmeister Посмотреть профиль Найти все сообщения от Freakmeister
 
Регистрация: 15.01.2011
Сообщений: 61

Нормального алгоритма для безглючной работы этого блока так и не придумал, пришлось рыть документацию по phpBB. В итоге сделал так:
$ignore=implode(',', array_keys($auth->acl_getf('!f_read', true))); //получаем список всех форумов, к которым у пользователя нет доступа

Ну а дальше - WHERE NOT IN($ignore)
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как научиться думать на javascript ? samuel Оффтопик 31 03.09.2013 02:10
При активации Disqus, не работает Nivo slider, как решить проблему? pinkfloyd Общие вопросы Javascript 0 30.05.2011 15:29
InnerHTML почему-то работает не так, как хотелось бы. помогите Dima00782 Общие вопросы Javascript 2 13.06.2010 21:17
Как работает обработчик onMouseMove() bayah Общие вопросы Javascript 3 29.04.2010 14:36
Как правильно послать XML в POST запросе LowCoder AJAX и COMET 10 15.07.2009 23:20