Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как оптимизировать ряд запросов?
 
 автор: Proger   (06.07.2008 в 19:30)   письмо автору
 
 

Здраствуйте, помогите пожалуйста.

SELECT cid,id FROM `photo-group`.`album` WHERE gid=3
SELECT name,id FROM `photo-group`.`cat` WHERE gid=3 ORDER BY `id` ASC
SELECT COUNT(apid) as count FROM `photo-group`.`photo` WHERE gid=3 AND ( aid=11 OR aid=10 OR aid=13 OR aid=12 OR aid=23)
SELECT COUNT(apid) as count FROM `photo-group`.`photo` WHERE gid=3 AND ( aid=1 OR aid=3 OR aid=4 OR aid=2 OR aid=5 OR aid=6 OR aid=7 OR aid=8 OR aid=9 OR aid=18 OR aid=19 OR aid=25)
SELECT COUNT(apid) as count FROM `photo-group`.`photo` WHERE gid=3 AND ( aid=14 OR aid=15 OR aid=16 OR aid=17 OR aid=20 OR aid=21 OR aid=22)
SELECT COUNT(apid) as count FROM `photo-group`.`photo` WHERE gid=3 AND ( aid=24)



Проблема в том что запросов типа:
SELECT COUNT(apid) as count FROM `photo-group`.`photo` WHERE gid=3 AND ( aid=14 OR aid=15 OR aid=16 OR aid=17 OR aid=20 OR aid=21 OR aid=22)


Может быть столько сколько и категорий в фотоальбомах...

Структура фотогалереи тупейшая:
Категория - альбом - фото

Моя задача: вывести количество альбомов в данной категории и количество фото в альбомах данной категории.

Возможно алгоритм изначально неправилен, прошу предложить решения.

   
 
 автор: cheops   (07.07.2008 в 01:36)   письмо автору
 
   для: Proger   (06.07.2008 в 19:30)
 

Для начала можно воспользоваться оператором IN, который позволит заменить запрос вида
SELECT COUNT(apid) as count FROM `photo-group`.`photo` 
WHERE gid=3 AND ( aid=14 OR aid=15 OR aid=16 OR aid=17 OR aid=20 OR aid=21 OR aid=22)

на
SELECT COUNT(apid) as count FROM `photo-group`.`photo` 
WHERE gid=3 AND aid IN (14, 15, 16, 17, 20, 21, 22)

Список (14, 15, 16, 17, 20, 21, 22) проще формировать, более того, его можно сформировать при помощи другого SELECT-запроса, образуя так называемый вложенный запрос.

   
 
 автор: Proger   (07.07.2008 в 20:01)   письмо автору
 
   для: cheops   (07.07.2008 в 01:36)
 

Хм... интерестно... я вот читал про вложенные запросы и тп, но не особо получилось найти нужный пример, а просто по мануалу скуля ничего не понял, можете подсказать конечное решение?

какие то там LEFT JOIN... который как бы "соединяет" результаты с одним ИД в однин общий... то есть возвращяет столбцы и оттуда и оттуда... но не понял как это поможет мне...

   
 
 автор: Proger   (07.07.2008 в 20:45)   письмо автору
 
   для: Proger   (07.07.2008 в 20:01)
 

Чтобы было ясней вот кусочек кода:

$q = "SELECT cid,id FROM `photo-group`.`album` WHERE gid=".$gid;
$r = mysql_query($q);

while($row = mysql_fetch_assoc($r)) {
$catalbum[$row['cid']][$row['id']] = true;
}

$query = "SELECT name,id FROM `photo-group`.`cat` WHERE gid=".$gid." ORDER BY `id` ASC";
$result = mysql_query($query);

while ($row = mysql_fetch_assoc($result)) {

$where = $cnt = null;

$cntalbum = count($catalbum[$row['id']]);

foreach ($catalbum[$row['id']] as $id=>$val) {
$cnt++;
$or = ' OR';
if ($cnt == 1) $or = null;
$where .= $or.' aid='.$id;
}

$query = "SELECT COUNT(apid) as count FROM `photo-group`.`photo` WHERE gid=".$gid." AND (".$where.")";
$r = mysql_query($query);
$r = mysql_fetch_assoc($r);
$cntcat = $r['count'];
...


$gid = номер группы лиц, где фотоальбом
$aid = ид альбома (он autoincrement относительно всего gid)
cid = ид категории, где находяться альбомы.

   
 
 автор: Proger   (12.07.2008 в 21:02)   письмо автору
 
   для: Proger   (07.07.2008 в 20:45)
 

Мда...облом. Никто не помог. :((

   
 
 автор: Trianon   (12.07.2008 в 21:30)   письмо автору
 
   для: Proger   (07.07.2008 в 20:45)
 

SELECT c.id, c.name, COUNT(p.apid) AS count 
FROM cat с 
  LEFT JOIN album a ON a.cid = c.id AND a.gid = c.gid
  LEFT JOIN photo p ON p.aid = a.id AND p.gid = a.gid
WHERE c.gid = $gid
GROUP BY c.id, c.name

   
 
 автор: Proger   (12.07.2008 в 22:12)   письмо автору
 
   для: Trianon   (12.07.2008 в 21:30)
 

Интерестно ... только немного не работает, пробую разбираться. Если что напишу. И за это БОЛЬШОЕ спасибо, ибо никто не хочел помогать!

   
 
 автор: Trianon   (12.07.2008 в 22:23)   письмо автору
 
   для: Proger   (12.07.2008 в 22:12)
 

я там слегка наврал. Сейчас исправлено.

   
 
 автор: Proger   (12.07.2008 в 22:45)   письмо автору
 
   для: Trianon   (12.07.2008 в 22:23)
 

Исправил в соответствии с вашей правкой:

id name count
1 Фото с пин-миксов 500
2 Школьные фото 733
3 Разное 520
4 Старые фотографии 0
5 Не моё, но мне нравится 72

все супер! Спасибо огромнейшее ;)

   
 
 автор: Trianon   (12.07.2008 в 23:01)   письмо автору
 
   для: Proger   (12.07.2008 в 22:45)
 

Собственно, можно и число альбомов посчитать здесь же:

SELECT c.id, c.name, COUNT(p.apid) AS count , COUNT(DISTINCT a.id) AS alcount 
FROM cat с 
  LEFT JOIN album a ON a.cid = c.id AND a.gid = c.gid
  LEFT JOIN photo p ON p.aid = a.id AND p.gid = a.gid
WHERE c.gid = $gid
GROUP BY c.id, c.name

   
 
 автор: Proger   (13.07.2008 в 13:15)   письмо автору
 
   для: Trianon   (12.07.2008 в 23:01)
 

это круто конечно, но моя гора запросов работала за 0.2 - 0.1 сек, а тут:

Отображает строки 0 - 4 (5 всего, запрос занял 0.6110 сек.)


Это нормально? что делать то? Может что нитак? Индексы проверять?

ЗЫ в таблице photo 1800 элементов, в album 29, в cat 5.

   
 
 автор: Trianon   (13.07.2008 в 13:55)   письмо автору
 
   для: Proger   (13.07.2008 в 13:15)
 

>это круто конечно, но моя гора запросов работала за 0.2 - 0.1 сек, а тут:
Так оставьте свою, в чем вопрос-то?

>ЗЫ в таблице photo 1800 элементов, в album 29, в cat 5.
Лично я не вижу ни одного.

   
 
 автор: Proger   (13.07.2008 в 17:14)   письмо автору
 
   для: Trianon   (13.07.2008 в 13:55)
 

Да нет конечно один запрос хорошо, я просто пытаюсь понять почему так? я может что-то нитак настроил в mysql? где ошибки искать?



album

Поле Тип Ноль По умолчанию Комментарии
id int(4) Нет
gid int(4) Нет
cid tinyint(3) Да NULL
author int(4) Нет
name varchar(50) Нет Без названия
desc varchar(255) Да NULL
whoisadmin tinyint(1) Нет 0
visible tinyint(1) Нет 0
original tinyint(1) Нет 0

cat

Поле Тип Ноль По умолчанию Комментарии
gid int(4) Нет
id tinyint(2) Нет
name varchar(50) Нет
author int(4) Нет

photo

Поле Тип Ноль По умолчанию Комментарии
gid int(4) Нет группа где фотоальбом
apid int(8) Нет уникальный ид фотки
pid int(4) Нет ид фотки в альбоме
aid int(4) Нет ид альбома, где фотка
zid int(4) Нет ид того, кто загрузил фотку
author varchar(50) Да NULL имя АВТОРА фотки
name varchar(50) Да NULL название фотки
desc varchar(255) Да NULL описание фотки
date datetime Нет дата загрузки (обработки) фото
editdate datetime Да NULL дата последнего изменения
size varchar(10) Нет размер фотки в байтах
view int(10) Да 0
file varchar(50) Нет имя файла фотки (800x600)
ofile varchar(50) Да NULL имя файла фотки (800x600)имя файла фотки (высота оригинала Х ширина оригинала))



индексы:

album

Имя индекса Тип Количество элементов Действие Поле
PRIMARY PRIMARY 29 id
gid INDEX Нет gid


cat

Имя индекса Тип Количество элементов Действие Поле
PRIMARY PRIMARY 5 id
gid INDEX Нет gid
name


photo

Имя индекса Тип Количество элементов Действие Поле
PRIMARY PRIMARY 1825 apid
gid INDEX 1825 gid
pid
aid
zid
author
name
desc
date
size
view
file
ofile

   
 
 автор: Trianon   (13.07.2008 в 17:18)   письмо автору
 
   для: Proger   (13.07.2008 в 17:14)
 

В первую очередь - в структуре таблиц.
Смотрите, как расставлены индексы.
Убирайте ненужные связи (это я про поле gid, которое у Вас повторяется везде.)
Смотрите план запроса.

   
 
 автор: Proger   (13.07.2008 в 17:30)   письмо автору
 
   для: Trianon   (13.07.2008 в 17:18)
 

Изменил индексы так чтобы то, что в запросе было единым индексом, быстродействия не прибавилось. Можно ссылку на доки про то как индекс составить правильно?

Отображает строки 0 - 4 (5 всего, запрос занял 0.5043 сек.)

   
 
 автор: Proger   (13.07.2008 в 18:39)   письмо автору
 
   для: Trianon   (13.07.2008 в 17:18)
 

Супер! Немного поразмышляв под музыку получил:

Отображает строки 0 - 4 (5 всего, запрос занял 0.0596 сек.)


!!!ПАСИБА!!!

   
 
 автор: Trianon   (13.07.2008 в 19:54)   письмо автору
 
   для: Proger   (13.07.2008 в 18:39)
 

Прикрепили бы архив с дампом...

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования