Задавайте вопросы, мы ответим
Вы не зашли.
Столкнулся с такой проблемой, не могу никак въехать как ее решить.
Имею 2 таблицы
Таблица объявлений (записей около 70000):
CREATE TABLE IF NOT EXISTS `boards` (
`id` int(11) NOT NULL auto_increment,
`board_category_id` int(11) NOT NULL default '0',
`board_type_id` int(11) NOT NULL default '0',
`user_id` int(10) unsigned default NULL,
`company_id` int(10) unsigned default NULL,
`company_name` varchar(255) NOT NULL default '',
`person` varchar(255) NOT NULL default '',
`country_id` int(10) unsigned default NULL,
`region_id` int(10) unsigned default NULL,
`city_id` int(10) unsigned default NULL,
`phone` varchar(50) NOT NULL default '',
`fax` varchar(50) NOT NULL default '',
`email` varchar(50) NOT NULL default '',
`www` varchar(255) NOT NULL default '',
`title` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `company_id` (`company_id`),
KEY `board_category_id` (`board_category_id`),
KEY `board_type_id` (`board_type_id`)
) ENGINE=MyISAM
Таблица рубрик (записей около 100):
CREATE TABLE IF NOT EXISTS `board_categories` (
`board_category_id` int(10) unsigned NOT NULL auto_increment,
`parent_id` int(10) default NULL,
`lft` int(10) default NULL,
`rght` int(10) default NULL,
`cat_name` varchar(255) default NULL,
PRIMARY KEY (`board_category_id`)
)
Так вот, самое странное
Вот запрос:
SELECT boards.id, boards.user_id, boards.created, boards.board_type_id, boards.title, boards.body, boards.country_id, boards.region_id, boards.city_id, board_categories.cat_name
FROM boards, board_categories
WHERE board_categories.board_category_id=boards.board_category_id and boards.board_type_id>0 ORDER BY created DESC LIMIT 22000, 10
Связь вы видите тут: board_categories.board_category_id=boards.board_category_id
Почему запрос так долго выполянтеся.
Я понимаю что время не очень большое, но сайт сами понимаете не из одного запроса.
Как оптимизировать запрос - базы?
Спасибо, с уважение Микола Великолепный
Неактивен
Ужас.
Посмотрите explain вашего запроса (и приведите его сюда).
Для boards будет использован полный перебор таблицы.
Подозреваю, что условию boards.board_type_id>0 соответствует большая часть таблицы. И вся эта куча данных, включая текстовые текстовые поля - body,title.., потом сортируется.
После этого отсчитывается 22000 строк и выдаются следующие 10 строк.
И всё это он делает всего лишь за 0.5 секунд
Неактивен
Кстати, по ключам посмотрите FAQ пункт 5
Собственно, решением в данном случае будет разбить запрос на два:
1) сначала найти нужные id из таблицы boards
2) по известным id выбрать нужную инфу из обеих таблиц.
Неактивен
Спасмбо за советы. Сегодня чуть позже отпишу результат.
Неактивен
EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE boards range board_category_id,board_type_id board_type_id 4 NULL 70326 Using where; Using filesort
1 SIMPLE board_categories eq_ref PRIMARY PRIMARY 4 b70441_24snab.boards.board_category_id 1 Using where
Неактивен
Мне кажется, что этот запрос вообще не должен выполняться. В нем написано
ORDER BY created DESC, а поля created нет ни в одной из таблиц
Да, а заметил я это потому, что нужен индекс по нему
Неактивен
По поводу Вашего совета.
Я так понял Вы советовали сделать выборку категорий, а потом объявы искать
то есть как то так
---
var str="12,13,14,15,16,17,18,11,1,2,3,4,5,6,7,8,34,56,86,78";
SELECT * FROM boards
WHERE boards.board_category_id IN(str)
ORDER BY created DESC
LIMIT 22000 , 10
В итоге у нас получается:
SELECT * FROM boards
WHERE boards.board_category_id IN(12,13,14,15,16,17,18,11,1,2,23, 3,4,5,6,7,8,34,56,86,78)
ORDER BY created DESC
LIMIT 22000 , 10
0.0393 сек.
Что очень хорошо.
Но вопрос по качеству кода, встеки хочется попрофессиональней все сделать,
такое решение хорошо смотрится ) ?
Неактивен
Смотрите, у вас условию board_type_id>0 соответствует 70326 строк. Это условие отсеивает какие-нибудь строки?
Может это условие не нужно, а проверку делать во внешнем приложении.
Неактивен
Это для надежности влепил (уже убрал) но без этого условия board_type_id>0 результат мало отличается 0.47.
Неактивен
Просто таблица не маленькая, но и не сильно большая. Интересно разобраться, как правильней сделать. Различные системы ведь работают с огромными данными из нескольких таблиц, и вроде летают, почему у меня так долго ).
Неактивен
Ваш первый и последний запрос немножко разные
Если говорить о первом запроосе, то я предлагал найти 10 id объявлений, а затем вытащить всю информацию из обеих таблиц для этих 10 объявлений.
Неактивен
Да я знаю, благодоря последнему запросу - я выбрал все объявы из нужных рубрик и вывеил только объявы без наименования рубрик.
Не проблема отдельно еще и в массив записать рубрики и в скрипте подставлять значение. Просто хотелось сделать хорошо )
Неактивен
Как бы по идее все просто 2 связанные таблицы - по идее должно быстро работать.
Неактивен
paulus написал:
Мне кажется, что этот запрос вообще не должен выполняться. В нем написано
ORDER BY created DESC, а поля created нет ни в одной из таблиц
Да, а заметил я это потому, что нужен индекс по нему
Точно. А ещё там поля body нет
Настоящий DDL таблицы покажите
Т.е. SHOW CREATE TABLE `boards`;
Неактивен
))) просто она большая ) поэтому и обрезал лишнее
CREATE TABLE IF NOT EXISTS `boards` (
`id` int(11) NOT NULL auto_increment,
`board_category_id` int(11) NOT NULL default '0',
`board_type_id` int(11) NOT NULL default '0',
`user_id` int(10) unsigned default NULL,
`company_id` int(10) unsigned default NULL,
`company_name` varchar(255) NOT NULL default '',
`person` varchar(255) NOT NULL default '',
`country_id` int(10) unsigned default NULL,
`region_id` int(10) unsigned default NULL,
`city_id` int(10) unsigned default NULL,
`phone` varchar(50) NOT NULL default '',
`fax` varchar(50) NOT NULL default '',
`email` varchar(50) NOT NULL default '',
`www` varchar(255) NOT NULL default '',
`title` varchar(255) NOT NULL default '',
`body` text NOT NULL,
`keyw` varchar(255) NOT NULL default '',
`views` int(10) unsigned NOT NULL default '0',
`created` datetime default NULL,
`modified` datetime default NULL,
`activ` int(1) NOT NULL default '0',
`moder` int(1) NOT NULL default '0',
`pars_url` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `company_id` (`company_id`),
KEY `board_category_id` (`board_category_id`),
KEY `board_type_id` (`board_type_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=70377 ;
Неактивен