2016-02-19 5 views
-1

У меня есть такие таблицы:Индексы Mysql таблицы

CREATE TABLE `skadate_newsfeed_action` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `entityId` int(11) NOT NULL, 
    `entityType` varchar(100) NOT NULL, 
    `feature` varchar(100) NOT NULL, 
    `data` longtext NOT NULL, 
    `status` varchar(20) NOT NULL DEFAULT 'active', 
    `createTime` int(11) NOT NULL, 
    `updateTime` int(11) NOT NULL, 
    `userId` int(11) NOT NULL, 
    `visibility` int(11) NOT NULL, 
    `privacy` enum('everybody','friends_only') NOT NULL DEFAULT 'everybody', 
    PRIMARY KEY (`id`), 
    KEY `userId` (`userId`), 
    KEY `privacy` (`visibility`), 
    KEY `updateTime` (`updateTime`), 
    KEY `entity` (`entityType`,`entityId`) 
) ENGINE=MyISAM; 

CREATE TABLE `skadate_profile` (
    `profile_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `email` varchar(128) NOT NULL DEFAULT '', 
    `username` varchar(32) NOT NULL DEFAULT '', 
    `password` varchar(40) NOT NULL, 
    `sex` bigint(20) DEFAULT NULL, 
    `match_sex` bigint(20) DEFAULT NULL, 
    `birthdate` date NOT NULL DEFAULT '0000-00-00', 
    `headline` varchar(128) DEFAULT '', 
    `general_description` text, 
    `match_agerange` varchar(6) DEFAULT NULL, 
    `custom_location` varchar(255) DEFAULT NULL, 
    `country_id` char(2) NOT NULL DEFAULT '', 
    `zip` varchar(10) DEFAULT NULL, 
    `state_id` varchar(5) DEFAULT NULL, 
    `city_id` int(11) DEFAULT '0', 
    `join_stamp` int(10) unsigned NOT NULL DEFAULT '0', 
    `activity_stamp` int(10) unsigned NOT NULL DEFAULT '0', 
    `membership_type_id` int(10) unsigned NOT NULL DEFAULT '18', 
    `affiliate_id` int(8) unsigned NOT NULL DEFAULT '0', 
    `email_verified` enum('undefined','yes','no') NOT NULL DEFAULT 'undefined', 
    `reviewed` enum('n','y') NOT NULL DEFAULT 'n', 
    `has_photo` enum('n','y') NOT NULL DEFAULT 'n', 
    `has_media` enum('n','y') NOT NULL DEFAULT 'n', 
    `status` enum('active','on_hold','suspended') NOT NULL DEFAULT 'active', 
    `featured` enum('n','y') NOT NULL DEFAULT 'n', 
    `register_invite_score` tinyint(3) NOT NULL DEFAULT '0', 
    `rate_score` tinyint(3) unsigned NOT NULL DEFAULT '0', 
    `rates` bigint(20) unsigned NOT NULL DEFAULT '0', 
    `language_id` int(10) unsigned NOT NULL DEFAULT '0', 
    `join_ip` int(11) unsigned NOT NULL DEFAULT '0', 
    `neigh_location` enum('country','state','city','zip') DEFAULT NULL, 
    `neigh_location_distance` int(10) unsigned NOT NULL DEFAULT '0', 
    `bg_color` varchar(32) DEFAULT NULL, 
    `bg_image` varchar(32) DEFAULT NULL, 
    `bg_image_url` varchar(255) DEFAULT NULL, 
    `bg_image_mode` tinyint(1) DEFAULT NULL, 
    `bg_image_status` enum('active','approval') NOT NULL DEFAULT 'active', 
    `has_music` enum('n','y') NOT NULL DEFAULT 'n', 
    `is_private` tinyint(1) NOT NULL DEFAULT '0', 
    `subscription_id_offerit` text, 
    PRIMARY KEY (`profile_id`), 
    UNIQUE KEY `email` (`email`), 
    UNIQUE KEY `username` (`username`), 
    KEY `membership_id` (`membership_type_id`), 
    KEY `zip` (`zip`), 
    KEY `country_id` (`country_id`), 
    KEY `state_id` (`state_id`), 
    KEY `city_id` (`city_id`), 
    KEY `sex` (`sex`), 
    KEY `match_sex` (`match_sex`), 
    KEY `activity_stamp` (`activity_stamp`), 
    KEY `join_stamp` (`join_stamp`), 
    KEY `birthdate` (`birthdate`), 
    KEY `featured` (`featured`,`has_photo`,`activity_stamp`) 
) ENGINE=MyISAM; 

и попытаться выполнить этот запрос:

SELECT DISTINCT `na`.* 
FROM `skadate_newsfeed_action` AS `na` 
LEFT JOIN `skadate_profile` AS `profile` ON (`na`.`userId` = `profile`.`profile_id`) 
WHERE (profile.email_verified='yes' OR profile.email_verified='no' OR profile.email_verified='undefined') 
AND `profile`.`status`='active' AND `na`.`status`='active' AND `na`.`privacy`='everybody' 
AND `na`.`visibility` & 1 AND `na`.`updateTime` < 1455885224 
ORDER BY `na`.`updateTime` DESC, `na`.`id` DESC 
LIMIT 0, 10 

Но когда я вижу EXPLAIN: enter image description here

Может быть кто-то может мне помочь , как я могу улучшить this запрос?

+0

Пожалуйста, объясните мне, почему вы ставите минус, спасибо. –

+0

Вам действительно нужно "LEFT"? Если нет, удалите его; то у Оптимизатора будет возможность начать с 'profile'. –

ответ

1

Если вы хотите получать записи только из одной таблицы, используйте exists, а не join и select distinct. Итак:

SELECT na.* 
FROM `skadate_newsfeed_action` na 
WHERE EXISTS (SELECT 1 
       FROM skadate_profile p 
       WHERE na.userId = p.profile_id AND 
        p.email_verified IN ('yes', 'no', 'undefined') AND 
        p.status = 'active' 
      ) AND 
     na.status = 'active' AND 
     na.privacy = 'everybody' AND 
     na.visibility & 1 > 0 AND 
     na.updateTime < 1455885224 
ORDER BY na.`updateTime` DESC, na.`id` DESC 
LIMIT 0, 10; 

Для этого запроса вы хотите индекс на skadate_profile(profile_id, status, verified). Кроме того, вероятно, полезно использовать следующий индекс: skadate_newsfeed_action(status, privacy, updateTime, visibility, userId).

+0

Создать индекс для пары 'email_verified' и' status', profile_id - PRIMARY, но похоже, что MySql не хочет использовать этот индекс: http://joxi.ru/v29PBx3fGOPDgm –

0

Возможно, это связано с ключевым словом DISTICT. Чтобы удалить дубликаты, MySQL должен сортировать результат по каждому выбранному столбцу.