2010-04-08 3 views
1

Я делаю соединение между таблицей «избранное» (3 миллиона строк) таблицы «items» (строки 600k). Запрос занимает от 0,3 секунды до 2 секунд, и я надеюсь, что смогу его оптимизировать.Нужна помощь в оптимизации запроса MYSQL с соединением

Favorites.faver_profile_id и Items.id индексируются. Вместо использования индекса faver_profile_id я создал новый индекс на (faver_profile_id, id), который исключил файловый сервер, необходимый при сортировке по id. К сожалению, этот индекс не помогает вообще, и я, вероятно, удалю его (yay, еще 3 часа простоя, чтобы сбросить индекс ..)

Любые идеи по оптимизации этого запроса?

В случае, если это помогает:
Favorite.removed и Item.removed являются "0" 98% времени.
Favorite.collection_id NULL около 80% времени.

SELECT `Item`.`id`, `Item`.`source_image`, `Item`.`cached_image`, `Item`.`source_title`, `Item`.`source_url`, `Item`.`width`, `Item`.`height`, `Item`.`fave_count`, `Item`.`created`   
FROM `favorites` AS `Favorite` 
LEFT JOIN `items` AS `Item` 
ON (`Item`.`removed` = 0 AND `Favorite`.`notice_id` = `Item`.`id`) 
WHERE ((`faver_profile_id` = 1) AND (`collection_id` IS NULL) AND (`Favorite`.`removed` = 0) AND (`Item`.`removed` = '0')) 
ORDER BY `Favorite`.`id` desc LIMIT 50; 

+----+-------------+----------+--------+----------------------------------------------------- ----------+------------------+---------+-----------------------------------------+------+-------------+ 
| id | select_type | table | type | possible_keys             | key    | key_len | ref          | rows | Extra  | 
+----+-------------+----------+--------+---------------------------------------------------------------+------------------+---------+-----------------------------------------+------+-------------+ 
| 1 | SIMPLE  | Favorite | ref | notice_id,faver_profile_id,collection_id_idx,idx_faver_idx_id | idx_faver_idx_id |  4 | const         | 7910 | Using where | 
| 1 | SIMPLE  | Item  | eq_ref | PRIMARY              | PRIMARY   |  4 | gragland_imgfavebeta.Favorite.notice_id | 1 | Using where | 
+----+-------------+----------+--------+---------------------------------------------------------------+------------------+---------+-----------------------------------------+------+-------------+ 

+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table  | Create Table                                                                                                                                                                                                 | 
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| favorites | CREATE TABLE `favorites` (
      `id` int(11) NOT NULL auto_increment COMMENT 'unique identifier', 
      `faver_profile_id` int(11) NOT NULL default '0', 
      `collection_id` int(11) default NULL, 
      `collection_order` int(8) default NULL, 
      `created` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'date this record was created', 
      `modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'date this record was modified', 
      `notice_id` int(11) NOT NULL default '0', 
      `removed` tinyint(1) NOT NULL default '0', 
       PRIMARY KEY (`id`), 
       KEY `notice_id` (`notice_id`), 
       KEY `faver_profile_id` (`faver_profile_id`), 
       KEY `collection_id_idx` (`collection_id`), 
       KEY `idx_faver_idx_id` (`faver_profile_id`,`id`) 
      ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 


+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                                                                                                                                                                                                                                                              | 
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| items |CREATE TABLE `items` (
     `id` int(11) NOT NULL auto_increment COMMENT 'unique identifier', 
     `submitter_id` int(11) NOT NULL default '0' COMMENT 'who made the update', 
     `source_image` varchar(255) default NULL COMMENT 'update content', 
     `cached_image` varchar(255) default NULL, 
     `source_title` varchar(255) NOT NULL default '', 
     `source_url` text NOT NULL, 
     `width` int(4) NOT NULL default '0', 
     `height` int(4) NOT NULL default '0', 
     `status` varchar(122) NOT NULL default '', 
     `popular` int(1) NOT NULL default '0', 
     `made_popular` timestamp NULL default NULL, 
     `fave_count` int(9) NOT NULL default '0', 
     `tags` text, 
     `user_art` tinyint(1) NOT NULL default '0', 
     `nudity` tinyint(1) NOT NULL default '0', 
     `created` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'date this record was created', 
     `modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'date this record was modified', 
     `removed` int(1) NOT NULL default '0', 
     `nofront` tinyint(1) NOT NULL default '0', 
     `test` varchar(10) NOT NULL default '', 
     `recs` text, 
     `recs_data` text, 
     PRIMARY KEY (`id`), 
     KEY `notice_profile_id_idx` (`submitter_id`), 
     KEY `content` (`source_image`), 
     KEY `idx_popular` (`popular`), 
     KEY `idx_madepopular` (`made_popular`), 
     KEY `idx_favecount_idx_id` (`fave_count`,`id`) 
     ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
+1

Не могли бы вы вывести вывод 'EXPLAIN SELECT' Item'.'id', ... '? – sfussenegger

+0

И определения таблиц тоже, результаты запроса 'show create table favorites' (а также для таблицы элементов) –

+0

Я добавил объяснение и покажу результаты создания таблицы выше. – makeee

ответ

0

Получить копию таблицы из резервной копии, и попытаться сделать индекс на Favorite таблицы, охватывающий все WHERE и JOIN условия, а именно (удалено, collection_id, profile_id). Сделайте то же самое с Item. Это может помочь, но сделает вставки потенциально намного медленнее.

Механизм SQL не будет использовать индекс, если ему все еще нужно выполнить полное сканирование таблицы из-за ограничений, не так ли?

+0

Я думаю, вы неправильно поняли. Я хочу, чтобы результаты были удалены = 0, поэтому я использую 98% таблицы. – makeee

+0

Rigth. Я удалил второй пункт сейчас. – hegemon

1

Прежде всего, вы заказываете по избранным.id, который представляет собой кластерный первичный ключ в таблице favorites. Для этого вам не понадобится: favorites - items вместо items - favorites.

Во-вторых, (Item. removed = '0') в ГДЕ есть избыток, поскольку такое же условие уже используется в JOIN.

В-третьих, изменить порядок условия в присоединиться к:

`Favorite`.`notice_id` = `Item`.`id` AND `Item`.`removed` = 0 

оптимизатор сможет использовать вас первичный ключ для индекса. Вы даже можете рассмотреть возможность создания индекса (id, remove) на таблице items.

Далее создайте (faver_profile_id, удален) индекс в favorites (или лучше обновление faver_profile_id индекса) и изменить порядок условий в WHERE к следующему:

(`faver_profile_id` = 1) 
AND (`Favorite`.`removed` = 0) 
AND (`collection_id` IS NULL) 

UPD: Я сожалею, я пропустили, что вы уже присоединились favorites до items. Тогда ORDER BY не требуется. Вы должны привести к чему-то вроде следующего:

SELECT 
    `Item`.`id`, 
    `Item`.`source_image`, 
    `Item`.`cached_image`, 
    `Item`.`source_title`, 
    `Item`.`source_url`, 
    `Item`.`width`, 
    `Item`.`height`, 
    `Item`.`fave_count`, 
    `Item`.`created`   
FROM `favorites` AS `Favorite` 
LEFT JOIN `items` AS `Item` 
ON (`Favorite`.`notice_id` = `Item`.`id` AND `Item`.`removed` = 0) 
WHERE `faver_profile_id` = 1 
    AND `Favorite`.`removed` = 0 
    AND `collection_id` IS NULL 
LIMIT 50; 

И еще одна вещь, когда у вас есть KEY idx_faver_idx_id (faver_profile_id, id) вам не нужно KEY faver_profile_id (faver_profile_id), потому что второй индекс просто дублирует половину из idx_faver_idx_id. Надеюсь, вы добавите второй указатель, как я и предложил.

+0

Я не вижу, почему мне не нужно «ORDER BY Favorites.id». Если я оставлю это, он закажет «Item.id ASC». Я не думаю, что индексирование (faver_profile_id, удалено) поможет много. Я могу вынуть Item.removed = 0 и Favorite.removed = 0 из запроса, и я все равно получаю одно и то же время выполнения. – makeee

Смежные вопросы