![]() |
Задавайте вопросы, мы ответим
Вы не зашли.

Можно здесь, конкретизируйте вопрос.
Неактивен
Лучше неверно будет тут продолжить, так будет понятнее ![]()
Здравствуйте! Нужна ваша профессиональная помощь. Нужно составить запрос, или запросы, для поиска картинок по ключевым словам.
Структура табличек:
Неактивен
Вот для примера часть странички, где виден результат работы, той задачи которую мы вчера решали, красным цветом подсвечиваются ключевые слова, которые еще повторяются в других картинках и рядом цифра сколько еще есть картинок с таким словом. А сейчас мы решаем задачку, когда пользователь нажмет на нужное ему слово, и начнется та самая выборка, и ему отобразятся все картинки, в которых есть такое слово, сначала из этой категории а потом из всех оставшихся.
Неактивен
Чего-то не получилось картинку вставить, не пойму как она тут у вас вставляется, нажал обзор, выбрал, а она не вставилась ![]()
О разобрался ![]()
Отредактированно Debian (15.08.2013 16:43:04)
Неактивен

Неактивен
1. Вместо * лучше явно указывать нужные поля.
Ага, я знаю, это просто для примера.
2. Необходимость тех или иных индексов зависит от запросов. Посмотрите FAQ №5
Тоже знаю, но там как раз все индексы почти для этой работы с ключевыми словами, кроме:
Неактивен

Вместо i.image_id очевидно нужно i.id
Неактивен
Вау
Безупречно
Возле меня сидит товарищ, у него, да что там у него, у нас обоих челюсти поотваливались ![]()
Супер, вы бог MySQL
Огромное приогромное Вам спасибо
В точности по каждому пункту из моего задания, все условия выполняются
Я уже люблю ваш форум
Тут одни настоящие профи.
А вот тут:
Отредактированно Debian (15.08.2013 17:54:25)
Неактивен
И вот что показывает explain:
mysql> explain SELECT i.* FROM images i JOIN
-> (SELECT DISTINCT image_id FROM tags WHERE tag='красивая') t ON i.id=t.image_id
-> ORDER BY if(category_id=5,1,2), i.id DESC;
+----+-------------+------------+--------+---------------+---------+---------+------------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+-----------------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 6 | Using temporary; Using filesort |
| 1 | PRIMARY | i | eq_ref | PRIMARY | PRIMARY | 4 | t.image_id | 1 | NULL |
| 2 | DERIVED | tags | ref | image_id,tag | tag | 152 | const | 6 | Using index condition; Using where; Using temporary |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+-----------------------------------------------------+
3 rows in set (0.00 sec)
mysql>
Это нормально или может как-то индексы еще нужно правильно сделать? Я просто в первые вижу такое <derived2>.
Неактивен

if(category_id=5,1,2)
если category_id = 5, то результатом функции будет 1, в противном случае 2
Таким образом в результате сортировки пойдут сначала картинки из 5ой категории, потом все остальные.
Средствами php вам нужно указывать только номер той категории, которая должна быть впереди. В данном примере это 5.
Неактивен
vasya написал:
if(category_id=5,1,2)
если category_id = 5, то результатом функции будет 1, в противном случае 2
Таким образом в результате сортировки пойдут сначала картинки из 5ой категории, потом все остальные.
Средствами php вам нужно указывать только номер той категории, которая должна быть впереди. В данном примере это 5.
Ааа, все, теперь я понял, спасибочки
А по индексам я так понял все нормально, вот это так и должно быть?
Неактивен

Debian написал:
Я просто в первые вижу такое <derived2>.
Это означает, что речь идет о таблице, полученной в результате выполнения подзапроса (см последнюю строку в explain, где тип доступа DERIVED и id=2).
Что касается улучшения, то разбивать на отдельные запросы. См http://webew.ru/articles/4856.webew
Неактивен
Хорошо, спасибо большое, почитаю сейчас ![]()
Неактивен
Сейчас немного поэксперементировал с индексами под этот запрос:
mysql> explain SELECT i.* FROM images i JOIN
-> (SELECT DISTINCT image_id FROM tags WHERE tag='красивая') t ON i.id=t.image_id
-> ORDER BY if(category_id=5,1,2), i.id DESC;
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 86 | Using temporary; Using filesort |
| 1 | PRIMARY | i | eq_ref | PRIMARY | PRIMARY | 4 | t.image_id | 1 | NULL |
| 2 | DERIVED | tags | ALL | NULL | NULL | NULL | NULL | 86 | Using where; Using temporary |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
3 rows in set (0.00 sec)
mysql> explain SELECT i.* FROM images i JOIN
-> (SELECT DISTINCT image_id FROM tags WHERE tag='красивая') t ON i.id=t.image_id
-> ORDER BY if(category_id=5,1,2), i.id DESC;
+----+-------------+------------+--------+---------------+---------+---------+------------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+-----------------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 6 | Using temporary; Using filesort |
| 1 | PRIMARY | i | eq_ref | PRIMARY | PRIMARY | 4 | t.image_id | 1 | NULL |
| 2 | DERIVED | tags | ref | tag | tag | 152 | const | 6 | Using index condition; Using where; Using temporary |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+-----------------------------------------------------+
3 rows in set (0.00 sec)
mysql> explain SELECT i.* FROM images i JOIN
-> (SELECT DISTINCT image_id FROM tags WHERE tag='красивая') t ON i.id=t.image_id
-> ORDER BY if(category_id=5,1,2), i.id DESC;
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 6 | Using temporary; Using filesort |
| 1 | PRIMARY | i | eq_ref | PRIMARY | PRIMARY | 4 | t.image_id | 1 | NULL |
| 2 | DERIVED | tags | ref | tag | tag | 152 | const | 6 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
3 rows in set (0.00 sec)
mysql> explain SELECT i.* FROM images i JOIN
-> (SELECT DISTINCT image_id FROM tags WHERE tag='красивая') t ON i.id=t.image_id
-> ORDER BY if(category_id=5,1,2), i.id DESC;
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 44 | Using temporary; Using filesort |
| 1 | PRIMARY | i | eq_ref | PRIMARY | PRIMARY | 4 | t.image_id | 1 | NULL |
| 2 | DERIVED | tags | range | tag | tag | 156 | NULL | 44 | Using where; Using index for group-by |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------------+
3 rows in set (0.01 sec)
mysql> explain SELECT i.* FROM images i JOIN
-> (SELECT DISTINCT image_id FROM tags WHERE tag='красивая') t ON i.id=t.image_id
-> ORDER BY if(category_id=5,1,2), i.id DESC;
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 6 | Using temporary; Using filesort |
| 1 | PRIMARY | i | eq_ref | PRIMARY | PRIMARY | 4 | t.image_id | 1 | NULL |
| 2 | DERIVED | tags | ref | tag | tag | 92 | const | 6 | Using where |
+----+-------------+------------+--------+---------------+---------+---------+------------+------+---------------------------------+
3 rows in set (0.00 sec)
mysql>
Какой из этих вариантов самый оптимальный? Я так понимаю, что наверно последний? И не поделитесь информацией, где можно почитать про explain, на русском и доступным понятным языком?
Неактивен

Третий.
Но основная проблема это Using filesort, который индексами не исправить. С другой стороны раньше времени можно и не оптимизировать, тем более, что в таблице у вас не хранится сама картинка, так что проблем с производительностью может и не быть.
Насчет русского не скажу, самое полное в доке (http://dev.mysql.com/doc/refman/5.5/en/ … utput.html), но есть русские переводы (хотя и устаревших версий, например, http://www.linuxlib.ru/mysqloff/EXPLAIN.html)
Неактивен
Спасибо ![]()
Неактивен
А можете еще немного подправить запрос? Я просто совсем забыл, что еще нужно получить имя категории, и логин пользователя, и они нужны в этомже запросе. Я приведу примеры как я делаю это для других типов выборки: по категориям, по цвету, и по всем, а также новый вид выборки, который вы мне дали, и покажу еще 2 таблички, `users` и `categories`, а Вы, если конечно это возможно, подправте пожалуйста запрос, который вы делали, а то совсем из головы вылетело, уже когда начал PHP реализовывать, вспомнил про эту деталь.
Таблички:
Неактивен

"SELECT ... FROM images i JOIN (SELECT DISTINCT image_id FROM tags WHERE tag='$sort') t JOIN `categories` JOIN `users`
ON i.id=t.image_id AND `images`.`category_id` = `categories`.`id` AND `images`.`user_id` = `users`.`id`
ORDER BY if(category_id=5,1,2), i.id DESC LIMIT $start, $limit"
Неактивен
Где-то что-то не так, ошибочка:
Отредактированно Debian (15.08.2013 21:48:53)
Неактивен
Наверно вы вот так хотели сделать? Просто вы назначили псевдоним images i а потом снова начали использовать images а не i.
Я не уверен проверьте пожалуйста, он заработал, но мало ли что.
Неактивен

`images`.`category_id` --> `i`.`category_id`
`images`.`user_id --> `i`.`user_id
Неактивен

Да, все так, только * в рабочем запросе писать не стоит.
Неактивен
Ага, уже сам догадался ) А еще подскажите, вот эти запросы что выше я показал, я просто их сам делал, но поскольку я не особо хорошо пока еще понимаю MySQL, может там что-то можно улучшить? Может я что-то не так сделал?
Неактивен
Да вот я как раз и думаю над этой звездочкой, дело в том что эти запросы используются и на сайте и в админке, в админке почти все поля нужны, на сайте нет, и если перечислять поля, то придется еще делать копию всех этих запросов, для админки и для сайта, + там полей много получается огромнейший кусок кода, в 8 запросов, которые по сути всего отличаются в пару полей, вот я и думаю, а стоит ли оно того? Действительно ли на столько разница?
Отредактированно Debian (15.08.2013 22:21:12)
Неактивен

Лишние данные выбираются, сортируются, передаются. Разница зависит от объема лишних данных и нагрузки. В вашем случае скорее всего невелика.
Ну и нужно учитывать, что даже если сегодня вам нужны все поля и вы поставили *, то завтра можете добавить в таблицу новые поля типа text/blob, которые в запросе не нужны, а * исправить забудете.
Неактивен