Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Проблема: очень долго выполняются определенные запросы (без JOIN-ов! но с 2 и более условиями).
Почему так, и как сделать чтобы быстро выполнялись?
Структура кластера:
- 2 сервера с data node (типы таблиц NDB 5.125)
- 2 сервера с sql node (версия MySQL 5.1),
- 1 сервер с management node
Конфигурация всех 5 серверов такая:
- Core 2 Quad, 8Gb RAM, 160GB 10000Rpm
Общий объём базы: 500 Мб
Общее количество таблиц: 31
1. Вот такой запрос тормозит (выполняется от 6 до 20 секунд):
SELECT SQL_CALC_FOUND_ROWS `user`.* FROM `user` WHERE (user_is_hidden IS NULL) AND (user_not_activated IS NULL) AND (user_inserted > '2008-09-02 15:00:05') AND (user_rate < 500) AND ((user_sex = 'm' ) AND ((user_age >= '21' AND user_age <= '25')) AND (user_city_id = '1' ) AND (user_country_id = '1' ) AND (user_collages > 0) AND (user_last_visit > '2008-09-04 00:00:00')) ORDER BY `user`.`user_id` DESC LIMIT 127
вот структура таблицы:
(Количество записей - около 100 000 (размер таблицы 13 Мб))
CREATE TABLE `user` ( `user_id` int(10) unsigned NOT NULL auto_increment, `user_name` varchar(255) default NULL, `user_phone` varchar(255) default NULL, `user_sex` char(2) default NULL, `user_foto_ext` varchar(255) default NULL, `user_clicks` int(11) default NULL, `user_clicks_last_ip` varchar(20) default NULL, `user_inserted` datetime default NULL, `user_updated` timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `user_last_visit` datetime default NULL, `user_is_premium` int(1) default NULL, `user_is_premium_from` datetime default NULL, `user_email` varchar(255) default NULL, `user_password` varchar(255) default NULL, `user_ip` varchar(22) default NULL, `user_cookie_id` varchar(32) default NULL, `user_id_from` int(11) default NULL, `user_id_group` int(11) default NULL, `user_age` int(11) default NULL, `user_birthday` date default NULL, `user_about` text, `user_city` varchar(255) default NULL, `user_country_id` smallint(5) unsigned default NULL, `user_city_id` int(10) unsigned default NULL, `user_auto_location` tinyint(1) default NULL, `user_last_mail` datetime default NULL, `user_sended_invites` int(11) default NULL, `user_rate` int(11) default NULL, `user_top` datetime default NULL, `user_is_hidden` tinyint(3) unsigned default NULL, `user_nospam` varchar(20) default NULL, `user_is_moder` tinyint(3) default NULL, `user_source` varchar(20) default NULL, `user_source_result` varchar(20) default NULL, `user_not_activated` tinyint(1) default NULL, `user_last_notify` datetime default NULL, `user_rotated` datetime default NULL, `user_ref_id` int(10) unsigned default NULL, `user_deviz` varchar(70) default NULL, `user_collages` smallint(5) unsigned default NULL, `user_why` text, `user_galleries` smallint(5) unsigned default NULL, PRIMARY KEY (`user_id`), KEY `i_cid` (`user_cookie_id`), KEY `i_user_from` (`user_id_from`), KEY `i_email` (`user_email`), KEY `i_us` (`user_source`), KEY `i_mixed` (`user_inserted`,`user_rate`,`user_is_hidden`,`user_not_activated`), KEY `i_rotate` (`user_is_hidden`,`user_sex`,`user_age`), KEY `i_name` (`user_name`), KEY `i_ccid` (`user_country_id`,`user_city_id`), KEY `i_collage` (`user_collages`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
-------
2. И вот такой (от 1 до 3 секунд) :
SELECT `game_user`.* FROM `game_user` WHERE ((gu_from_user_id = '51124' OR gu_to_user_id = '51124'))
стурктура таблицы:
(Количество записей - тоже около 100 000 (размер 5 Мб.))
CREATE TABLE `game_user` ( `gu_id` int(11) unsigned NOT NULL auto_increment, `game_id` int(11) default NULL, `gu_from_user_id` int(11) default NULL, `gu_from_user_sex` char(3) default NULL, `gu_to_user_id` int(11) default NULL, `gu_to_user_sex` char(3) default NULL, `gu_started` datetime default NULL, `gu_closed` datetime default NULL, `gu_status` varchar(20) default NULL, `gu_last_message_w` tinyint(4) default NULL, `gu_last_message_m` tinyint(4) default NULL, PRIMARY KEY (`gu_id`), KEY `ddddfff` (`gu_from_user_id`,`gu_from_user_sex`,`gu_last_message_w`), KEY `ffffdddd` (`gu_from_user_id`,`gu_from_user_sex`,`gu_last_message_m`), KEY `ffhbfrty` (`gu_from_user_id`,`gu_to_user_id`), KEY `xxx` (`game_id`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
На обычном mysql эти запросы выполняются в 0.05 секунд самое долгое.
Скажите, это нормальная ситуация?
Как её можно решить?????? Всем заранее благодарен за помощь
Неактивен
Проблема в том, что у Вас используется кластер. Для того, чтобы получить данные
по запросу, не использующему индекс, в случае дисковой таблицы 13 мегабайт - Вам
нужно потратить несколько миллисекунд для вытаскивания всей таблицы. В то же время,
вытаскивание всех строк с кластера - это очень неблагодарный процесс (т.к. данные
нужно притащить со всех датанод на SQL-ноду и на ней выкинуть ненужные).
Кластер будет оптимально работать в случае, когда Вы будете делать точечные запросы
по данным (т.е. во втором случае, подозреваю, что хватит добавления ключа на gu_to_user_id),
в этом случае условия будут проталкиваться на датаноды, и оттуда будут забираться
только нужные строки.
Для первого запроса я бы попробовал ключ на user_age / user_last_visit в зависимости от
селективности, хотя я не уверен, что range-запросы протолкнутся на датаноды.
P.S. У нас есть специалист по кластеру, возможно, он ответит более полно.
Неактивен
Есть определенные условия, при которых WHERE обрабатывается на дата-нодах, не требуя вытаскивания всей таблицы на SQL-ноду. Механизм описан в документации: http://dev.mysql.com/doc/refman/5.0/en/ … ation.html
На практике.
1. убедитесь, что переменная engine_condition_pushdown=1
2. Сделайте EXPLAIN запросу и убедитесь, что в комментариях присутствует упоминание "condition pushdown"
Неактивен
Страниц: 1