Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Вывести разделы, на которые подписаны пользователи

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
dzheka3d
Отправлено: 18 Сентября, 2014 - 22:08:38
Post Id



Гость


Покинул форум
Сообщений всего: 77
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




Здравствуйте! Стоит такая задача
Есть таблица, в которой хранятся подписки пользователей на разделы сайта:

Нужно вывести все разделы, на которые подписаны пользователи, которые имеют в подписках раздел "1"
т.е. вывод должен быть таким


Получить результат можно вот таким запросом:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM `feed` WHERE `user_id` IN(SELECT `user_id` FROM `feed` WHERE `category_id`=1)

Но при 100 тыс. записей в таблице, он выполняется 10 секунд


/

(Отредактировано автором: 18 Сентября, 2014 - 22:11:15)

 
 Top
teddy
Отправлено: 18 Сентября, 2014 - 22:16:24
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




удалено

(Отредактировано автором: 18 Сентября, 2014 - 23:18:09)

 
 Top
dzheka3d
Отправлено: 18 Сентября, 2014 - 22:54:48
Post Id



Гость


Покинул форум
Сообщений всего: 77
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




Этот запрос выведет только записи, в которых category_id = 1
А мне нужно именно остальные записи тех user_id в которых присутствует category_id = 1
Не совсем наверное я правильно перефразировал, поэтому, лучше наверное в первом посте объяснил
Т.е. мне нужны именно эти записи:






/

(Отредактировано автором: 18 Сентября, 2014 - 22:57:19)

 
 Top
teddy
Отправлено: 18 Сентября, 2014 - 23:17:47
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




Да. Вы правы, я неверно понял задачу.

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

(Отредактировано автором: 18 Сентября, 2014 - 23:25:59)

 
 Top
dzheka3d
Отправлено: 18 Сентября, 2014 - 23:28:44
Post Id



Гость


Покинул форум
Сообщений всего: 77
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




Попробую, но мне кажется скорость от этого не сильно изменится...
 
 Top
teddy
Отправлено: 19 Сентября, 2014 - 00:15:41
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




Про отдельную выборку id это я к тому, что использование подзапросов в IN лишает СУБД возможности использовать индексы. Поэтому при большом количестве данных обычно вешается индекс на поле, которое используется как IN, а в скобки IN передается уже заранее известные значения.

Вообще странно такое поведение. По сути 100к записей это фигня.

Стало интересно, создал таблицу по Вашим данным на своей задрыпанной машине, и Ваш запрос выполнился у меня за 1 секунду.

Уверены, что проблема в запросе?
 
 Top
Sail
Отправлено: 19 Сентября, 2014 - 08:20:14
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




dzheka3d, потестируйте такой запрос:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT `user_id`, `category_id` FROM `tablename` JOIN (
  2.   SELECT `user_id` FROM `tablename` WHERE `category_id` = '1'
  3. ) sub_1 USING (`user_id`)
 
 Top
Мелкий Супермодератор
Отправлено: 19 Сентября, 2014 - 09:42:04
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




teddy пишет:
использование подзапросов в IN лишает СУБД возможности использовать индексы.

Не лишает.
Но у MySQL, особенно если у вас древняя версия, этак до 5.5 - подзапросы работают большей частью отвратно. Оптимизатор неверно переписывает запрос.

Джойн на подзапрос (как показал Sail) или на самого себя такой проблемы не имеет и работает нормально.

Вариация Sail'а, но без подзапроса за ненадобностью:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t.`user_id`, t.`category_id` FROM `tablename` AS t JOIN `tablename` AS cat USING (`user_id`) WHERE cat.`category_id` = '1'

Надо поиграться с explain'ом, но дополнительно ускорит индекс по category_id & user_id или user_id & category_id - не могу сообразить, какой именно оптимизатору понравится.


-----
PostgreSQL DBA
 
 Top
Sail
Отправлено: 19 Сентября, 2014 - 09:49:48
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




Мелкий пишет:
но без подзапроса за ненадобностью

Вот что меня смущало при отправке сообщения! Улыбка
Ну и в довесок:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT t1.`user_id`, t1.`category_id` FROM `tablename` t1 JOIN `tablename` AS cat
  2. ON cat.`category_id` = '1' AND t1.`user_id` = cat.`user_id`
 
 Top
dzheka3d
Отправлено: 19 Сентября, 2014 - 12:27:45
Post Id



Гость


Покинул форум
Сообщений всего: 77
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




teddy пишет:
Уверены, что проблема в запросе?

Да, уверен был, т.к. тестировал именно в самой mysql и на php, сервер мощный.

Спасибо ребята всем, оставил запрос Sail, выполняется за 0.04 сек. на легке

Подскажите может книжки по mysql, по которым учились, а то как-то примитивно я запросы составляю...
 
 Top
Мелкий Супермодератор
Отправлено: 19 Сентября, 2014 - 14:08:07
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




High Performance MySQL: http://shop[dot]oreilly[dot]com/product/0636920022343[dot]do
Не сказать что рекомендую - она обязательна к прочтению всем, кто работает с этой СУБД.


-----
PostgreSQL DBA
 
 Top
teddy
Отправлено: 19 Сентября, 2014 - 18:11:10
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




Мелкий пишет:
Не лишает.

Да, все верно. Я ошибся. Спасибо, что поправили.
Прошу прощения у автора за дезинформацию.

Помню где то читал, что MySQL не использует индексы в подзапросах, поверил на слово и даже не удосужился сделать EXPLAIN для проверки. Ну, сам дурак как говорится.. )
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB