Тормозящий запрос в IPB

x-yuri

Новичок
Все дело в том что даже если ключи есть
и у MySQL вроде и нет причин пробегать всю таблицу
изза ORDER BY + JOIN он всеравно будет это делать...
ну вот алергия у него и всё тут)
т.е. ему в лом?

-~{}~ 28.01.09 19:14:

BRat а вообще, я думаю, Gas имел в виду limit в подзапрос вставить

-~{}~ 28.01.09 19:15:

по-крайней мере попробовать можно
 

x-yuri

Новичок
BRat а можешь кинуть ссылку на дамп этих двух таблиц? я у себя попробую, хотя вряд ли что-то придумаю
 

BRat

o_0
x-yuri
да ладно, сделаю два отдельных запроса. Наврядли тут что-то быстрее можно придумать. При существующей структуре.

Структуру могу кинуть, а данные не разрешат )
 

BRat

o_0
x-yuri на обилие индексов внимания не обращай. Это результаты экспериментов ) не убрали ещё.

[sql]
CREATE TABLE IF NOT EXISTS `inv_posts` (
`pid` int(10) NOT NULL auto_increment,
`append_edit` tinyint(1) default '0',
`edit_time` int(10) default NULL,
`author_id` mediumint(8) NOT NULL default '0',
`author_name` varchar(32) default NULL,
`use_sig` tinyint(1) NOT NULL default '0',
`use_emo` tinyint(1) NOT NULL default '0',
`ip_address` varchar(16) NOT NULL default '',
`post_date` int(10) default NULL,
`icon_id` smallint(3) default NULL,
`post` text,
`queued` tinyint(1) NOT NULL default '0',
`topic_id` int(10) NOT NULL default '0',
`post_title` varchar(255) default NULL,
`new_topic` tinyint(1) default '0',
`edit_name` varchar(255) default NULL,
`post_key` varchar(32) NOT NULL default '0',
`post_parent` int(10) NOT NULL default '0',
`post_htmlstate` smallint(1) NOT NULL default '0',
`post_edit_reason` varchar(255) NOT NULL default '',
PRIMARY KEY (`pid`),
KEY `author_id` (`author_id`,`topic_id`),
KEY `post_date` (`post_date`),
KEY `topic_id` (`topic_id`,`queued`,`pid`,`post_date`),
KEY `post_key` (`post_key`),
KEY `ip_address` (`ip_address`),
KEY `topic_id_pid` (`topic_id`,`pid`),
FULLTEXT KEY `post` (`post`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;


CREATE TABLE IF NOT EXISTS `inv_topics` (
`tid` int(10) NOT NULL auto_increment,
`title` varchar(250) NOT NULL default '',
`description` varchar(70) default NULL,
`state` varchar(8) default NULL,
`posts` int(10) default NULL,
`starter_id` mediumint(8) NOT NULL default '0',
`start_date` int(10) default NULL,
`last_poster_id` mediumint(8) NOT NULL default '0',
`last_post` int(10) default NULL,
`icon_id` tinyint(2) default NULL,
`starter_name` varchar(32) default NULL,
`last_poster_name` varchar(32) default NULL,
`poll_state` varchar(8) default NULL,
`last_vote` int(10) default NULL,
`views` int(10) default NULL,
`forum_id` smallint(5) NOT NULL default '0',
`approved` tinyint(1) NOT NULL default '0',
`author_mode` tinyint(1) default NULL,
`pinned` tinyint(1) default NULL,
`moved_to` varchar(64) default NULL,
`total_votes` int(5) NOT NULL default '0',
`topic_hasattach` smallint(5) NOT NULL default '0',
`topic_firstpost` int(10) NOT NULL default '0',
`topic_queuedposts` int(10) NOT NULL default '0',
`topic_rating_total` smallint(5) unsigned NOT NULL default '0',
`topic_rating_hits` smallint(5) unsigned NOT NULL default '0',
`topic_open_time` int(10) NOT NULL default '0',
`topic_close_time` int(10) NOT NULL default '0',
PRIMARY KEY (`tid`),
KEY `topic_firstpost` (`topic_firstpost`),
KEY `forum_id` (`forum_id`,`pinned`,`approved`),
KEY `last_post` (`forum_id`,`pinned`,`last_post`),
KEY `state` (`state`),
KEY `approved` (`approved`),
KEY `forum_id_state_approved` (`forum_id`,`state`,`approved`),
FULLTEXT KEY `title` (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
[/sql]

-~{}~ 01.02.09 22:53:

Переписал я этот запрос в два. Первый получает id шники тем, работает супер. Со вторым проблемы
[sql]
SELECT p.*,t.title AS topic_title, t.starter_name AS topic_starter_name, t.forum_id FROM inv_posts p LEFT JOIN inv_topics t ON ( t.tid=p.topic_id ) WHERE p.topic_id IN (очень много id шников) ORDER BY p.pid desc LIMIT 0,10
[/sql]

всё почти также, время выполнения никуда не годится, slow log показывает время 7-10сек.

Код:
id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra
1 	SIMPLE 	p 	range 	topic_id,topic_id_pid 	topic_id 	4 	NULL 	163141 	Using where; Using filesort
1 	SIMPLE 	t 	eq_ref 	PRIMARY 	PRIMARY 	4 	forum.p.topic_id 	1
Даже не знаю, что делать. Можно еще как-то этот запрос упростить? Или копать в другом направлении?

Встраивание кеширования последних постов для каждого форума было бы идеальным, но ИПБ это такой говнофорум, что мне сложно предсказать сколько времени это займет, и какие косяки вылезут. Но на данный момент это моя единственная идея
 

x-yuri

Новичок
еще есть идея выбирать n последних постов, а в пхп уже выбирать нужные (t.forum_id = 40 AND t.state != "link" AND t.approved = 1), как-то так
 

nalim

Новичок
Как вариант , правда не факт что сильно оптимальный можно выбирать только ключи
(чтобы было поменьше данных) без лимита и сортировки
а потом сортировать внутри PHP
и уже по сортированному списку id делать выборку данных
 

BRat

o_0
x-yuri
хм, в этот форум пишут намного чаще чем в другие. Наверное это и вариант для него, надо попробовать. Спасибо!
 

x-yuri

Новичок
BRat
кстати идею можно в один запрос реализовать или в 2 (сначала только id)
кроме того, можно выбрать оптимальное n и в конце, если не получили нужное количество постов (и если это действительно важно), повторить всю процедуру с n=2*n (или другим коеффициентом)
 

BRat

o_0
nalim
там массив из 150 тысяч эл. получается. Думаю PHP с сортировкой будет работать не быстрее MySQL. Хотя попробовать тоже можно, спасибо

-~{}~ 07.02.09 17:13:

Спасибо x-yuri, сделал как ты предложил.
 
Сверху