|
PHP / MySQL Создание динамических Веб-ресурсов |
26.03.2013, 12:42
|
#1
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Возможно ли оптимизировать получение данных из двух таблиц
В общем есть две таблицы
user_items
и user_item_params
Получаю из них данные следующим образом:
public function items_getUserItems($user_id) { $sth = $this->dbh->prepare('SELECT * FROM user_items WHERE user = :user_id'); $sth->execute(array( ':user_id' => intval($user_id), ));
$items= $sth->fetchAll(PDO::FETCH_ASSOC);
$sth = $this->dbh->prepare('SELECT * FROM user_item_params WHERE item = :item_id');
$count = count($items); for($i=0; $i<$count; $i++) { $sth->execute(array( ':item_id' => intval($items[$i]['id']), )); $items[$i]['params'] = $sth->fetchAll(PDO::FETCH_ASSOC); }
return $items; }
Возможно ли это оптимизировать и не делать для каждого юзер_итема запрос его параметров?
|
(Offline)
|
|
26.03.2013, 12:59
|
#2
|
Разработчик
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений (для 1,072 пользователей)
|
Ответ: Возможно ли оптимизировать получение данных из двух таблиц
|
(Offline)
|
|
26.03.2013, 13:14
|
#3
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Возможно ли оптимизировать получение данных из двух таблиц
Мне надо передать на клиент результат в формате json, join мне даст одну таблицу, придется делать хитрый алгоритм для преобразования если я хочу, чтобы результат выглядел как сейчас.
|
(Offline)
|
|
26.03.2013, 13:34
|
#4
|
Разработчик
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений (для 1,072 пользователей)
|
Ответ: Возможно ли оптимизировать получение данных из двух таблиц
оптимально все сделать одним запросом, а цикл потом для обработки все равно нужен, т.к. mysql в json может выбрать тока при EXPLAIN, и то с версии 5.6
вроде так:
SELECT * FROM user_items LEFT JOIN user_item_params ON user_items.items=user_item_params.item WHERE user=userid
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
26.03.2013, 14:08
|
#5
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Возможно ли оптимизировать получение данных из двух таблиц
Посоветовали мне получить параметры итемов отдельно одним запросом и получилось следующее
public function items_getUserItems($user_id) { $sth = $this->dbh->prepare('SELECT * FROM user_items WHERE user = :user_id'); $sth->execute(array( ':user_id' => intval($user_id), )); $items = $sth->fetchAll(PDO::FETCH_ASSOC); $count = count($items); $item_ids = array(); $item_index = array(); for($i=0; $i<$count; $i++) { $items[$i]['params'] = array(); $item = $items[$i]; $item_ids[] = $item['id']; $item_index[$item['id']] = $i; } $sth = $this->dbh->prepare('SELECT * FROM user_item_params WHERE item IN ('.implode(', ', $item_ids).');'); $sth->execute(); $item_params = $sth->fetchAll(PDO::FETCH_ASSOC); foreach($item_params as $item_pram) { $item = $item_pram['item']; unset($item_pram['item']); $items[$item_index[$item]]['params'][] = $item_pram; } return $items; }
А еще я обдумывал вариант с параметрами в поле первой таблицы в виде json строки...
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
26.03.2013, 15:06
|
#6
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: Возможно ли оптимизировать получение данных из двух таблиц
Сразу подмечу, что если у тебя индексация в обоих таблицах хорошо настроина, то запросы будут весьма оптимальны даже при двух запросах.
Но. Тут важна суть не в запросах, а в том кто эти данные получает и что с ними делает.
Например если у тебя игра происходят матчами, и по геймплаю шмот менять можно только между матчами, то при старте матча ты получаешь эти данные один раз, что совсем не критично.
А если можно менять шмот (влиять на бд) во время матча, тогда загружай данные в начале матча, и храни в процессе что обсчитывает матч, и при изменениях - меняй игровые данные и посылай UPDATE в бд, но не перезагружай данные.
Тупой кеш в памяти.
Да и насчёт JSON'а, я тебе настоятельно рекомендую пересмотреть хотя бы на будущее представление о том как данные хранятся в БД. Ты используешь SQL базу данных, с таблицами, но преобразуешь в вложенные JSON документы.
Посмотри в сторону NoSQL баз данных, таких как MongoDB - легко ставиться, очень проста в использовании. Важный плюс в том что там нету таблиц, и всяких JOIN'ов (хотя это сильно влияет на то как данные хранятся, и не всегда подойдёт), зато есть сложные формы объектов, с вложенностями, массивами, хеш таблицами и т.п. Что как я вижу просто идеально подходит под то что ты пытаешься сделать в коде выше.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
|
|
26.03.2013, 15:53
|
#7
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Возможно ли оптимизировать получение данных из двух таблиц
Спасибо за советы. NoSQL в данном случае не подходит, т.к. я на хостинг ничего не могу поставить сам.
По поводу получения - данные меняться будут редко, и не во время боя. И я всетаки решил сделать все в первой таблице. Я создал в ней текстовое поле params и в виде json буду хранить там параметры.
В итоге получилось вот так:
public function items_getUserItems($user_id) { $sth = $this->dbh->prepare('SELECT * FROM user_items WHERE user = :user_id'); $sth->execute(array( ':user_id' => intval($user_id), ));
$items = $sth->fetchAll(PDO::FETCH_ASSOC);
$count = count($items);
for($i=0; $i<$count; $i++) { $items[$i]['params'] = json_decode($items[$i]['params'], true); if($items[$i]['params'] == null) { unset($items[$i]['params']); } }
return $items; }
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 08:58.
|