Поругайте структуру БД

alpine

Новичок
kuchin
На данный момент это бежит на Apache 2.0, MySQL 3.23, собираюсь переносить на более новую версию, чтобы воспользоваться SELECT'ами внутри SELECT'ов и транзакциями (4.1 вроде должно хватить для этого? Или надо сразу 5?).
А ты что mySQL поднял до >= 4.1?! Или это у тебя тестовый сервер?
 

kuchin

Новичок
Блин. Наврал я все :)
Этот запрос как раз нормально отрабатывает...
Извините. Вот проблемный запрос:
Код:
explain SELECT COUNT(DISTINCT p.itemid)
FROM items AS p
INNER JOIN tags_of AS t0
	ON p.itemid = t0.itemid
	AND t0.tagid = 1515
INNER JOIN tags_of AS t1
	ON p.itemid = t1.itemid
	AND t1.tagid = 536
INNER JOIN tags_of AS t2
	ON p.itemid = t2.itemid
	AND t2.tagid = 925
INNER JOIN tags_of AS t3
	ON p.itemid = t3.itemid
	AND t3.tagid = 541
Код:
+----+-------------+-------+--------+-----------------------------------------+---------+---------+------------------------+------+--------------------------+
| id | select_type | table | type   | possible_keys                           | key     | key_len | ref                    | rows | Extra                    |
+----+-------------+-------+--------+-----------------------------------------+---------+---------+------------------------+------+--------------------------+
|  1 | SIMPLE      | t3    | ref    | PRIMARY,itemid,tagid,itemmember,tagitem | tagid   |       4 | const                  |  654 | Using where; Using index |
|  1 | SIMPLE      | p     | eq_ref | PRIMARY                                 | PRIMARY |       4 | progs.t3.itemid        |    1 | Using index              |
|  1 | SIMPLE      | t1    | ref    | PRIMARY,itemid,tagid,itemmember,tagitem | tagitem |       8 | const,progs.p.itemid   |    1 | Using where; Using index |
|  1 | SIMPLE      | t2    | ref    | PRIMARY,itemid,tagid,itemmember,tagitem | tagitem |       8 | const,progs.p.itemid   |    1 | Using where; Using index |
|  1 | SIMPLE      | t0    | ref    | PRIMARY,itemid,tagid,itemmember,tagitem | tagitem |       8 | const,progs.p.itemid   |    1 | Using where; Using index |
+----+-------------+-------+--------+-----------------------------------------+---------+---------+------------------------+------+--------------------------+
-~{}~ 30.08.05 17:38:

alpine: да, я перенес с shared hosting на virtual dedicated server, и проапгрейдил до PHP 5.0, MySQL 4.1
 

alpine

Новичок
Falc
У тебя теги по нескольку раз повторяются, сделай первичный ключ на programs2tags и будет ок.
Таблица programs2tags связывает таблицы programs и tags, и tags_id там и должны повторятся, если я правильно понял ...
 

Falc

Новичок
kuchin
Судя по эксплейну не должно быть тут тормозов. Возможно у тебя есть тег к которому принадлежат почти все программы и когда по нему идет поиск тогда и тормозит.

-~{}~ 30.08.05 18:42:

alpine
>>Таблица programs2tags связывает таблицы programs и tags, и tags_id там и должны повторятся, если я правильно понял

Какой смысл программе один и тот же тег 2 раза ставить?
 

kuchin

Новичок
Falc: да, именно так, по этим тегам и тормозит...
Вопрос, можно ли посчитать кол-во программ каким-то другим запросом?

-~{}~ 30.08.05 17:48:

А то так получается что запрос данных, который возвращает всего 3-4 элемента, отрабатывает 0.5 секунды, а запрос посчитать сколько этих самых данных - в сотни раз больше...
 

Falc

Новичок
kuchin
>>Вопрос, можно ли посчитать кол-во программ каким-то другим запросом?
См. выше

-~{}~ 30.08.05 18:50:

Falc
>>запрос данных, который возвращает всего 3-4 элемента, отрабатывает 0.5 секунды

Это ты про какой запрос?
 

Falc

Новичок
alpine
Если ты посмотришь на explain'ы то и у kuchin'а там тоже первичный ключ.
 

kuchin

Новичок
Falc
"См. выше" - куда?
Насчет запроса - тот же самый запрос только без COUNT и с LIMIT (на предыдущей странице) отрабатывает в сотню раз быстрее.
 

Falc

Новичок
kuchin
>>тот же самый запрос только без COUNT и с LIMIT (на предыдущей странице) отрабатывает в сотню раз быстрее.

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

>>"См. выше" - куда?

Я про тот запрос, который написал alpine, а я немного модифицировал. Хотя я не думаю что он будет быстрее.

Вообще такой запрос - это слабое место мускула, тут нужно строить гистограму, но мускул - этого не умеет. Если критично быстродействие можно построить ее самому, но это гиморой.
 

kuchin

Новичок
Falc
Что-то я не соображу как твой запрос привести к общему COUNT(). Там идет GROUP BY, и COUNT показывает не то что надо...
 

Falc

Новичок
kuchin

Оберни еще одним селектом, хотя скорость можно проверить и без count :)
 

alpine

Новичок
kuchin
Покажи результирующий запрос и время его выполнения плз. :)
 

kuchin

Новичок
Пока еще не было времени переделать запрос. Другие заботы. Поднял второй сайт...
Как только переделаю - обязательно здесь напишу.

-~{}~ 30.09.05 00:22:

Переделал запрос - он теперь выглядит так:
Код:
SELECT COUNT(*) AS count FROM (SELECT ...... ) AS X
И все действительно быстро отрабатывает.
 
Сверху