Задавайте вопросы, мы ответим
Вы не зашли.
Можно здесь, конкретизируйте вопрос.
Неактивен
Лучше неверно будет тут продолжить, так будет понятнее
Здравствуйте! Нужна ваша профессиональная помощь. Нужно составить запрос, или запросы, для поиска картинок по ключевым словам.
Структура табличек:
Неактивен
Вот для примера часть странички, где виден результат работы, той задачи которую мы вчера решали, красным цветом подсвечиваются ключевые слова, которые еще повторяются в других картинках и рядом цифра сколько еще есть картинок с таким словом. А сейчас мы решаем задачку, когда пользователь нажмет на нужное ему слово, и начнется та самая выборка, и ему отобразятся все картинки, в которых есть такое слово, сначала из этой категории а потом из всех оставшихся.
Неактивен
Чего-то не получилось картинку вставить, не пойму как она тут у вас вставляется, нажал обзор, выбрал, а она не вставилась
О разобрался
Отредактированно 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, которые в запросе не нужны, а * исправить забудете.
Неактивен