Медленное присоединение?NULL ссылка, которая лучше - PullRequest
0 голосов
/ 02 апреля 2011

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

CREATE TABLE `bb_index` (
  `bb_id` smallint(5) unsigned NOT NULL,
  `object_id` bigint(10) unsigned NOT NULL,
  `in_object_id` bigint(10) unsigned NOT NULL,
  `f` int(10) unsigned DEFAULT NULL,
  `length` decimal(10,5) DEFAULT NULL,
  PRIMARY KEY (`bb_id`,`object_id`,`in_object_id`),
  KEY `in_obj_key` (`bb_id`,`in_object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


CREATE TABLE `obj_bb_relation` (`bb_id` smallint(5) unsigned NOT NULL DEFAULT '0',
  `object_id` bigint(10) unsigned NOT NULL DEFAULT '0',
  `object_bb_f` int(11) unsigned DEFAULT NULL,
  PRIMARY KEY (`bb_id`,`object_id`),
  KEY `object_id` (`object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Что лучше: Вариант 1:

SELECT object_id, f, length , object_bb_freq as C 
  FROM (select object_id, f, length 
          from bb_index use index (in_obj_key) 
         where bb_id = 14 
           and in_object_id = XXX
       ) as a join obj_bb_relation as b using (object_id)

ОБЪЯСНЕНИЕ:

enter image description here

Вариант 2:

SELECT object_id, f, length, object_bb_f AS C 
  FROM bb_index AS a 
  JOIN obj_bb_relation AS b USING ( object_id ) 
 WHERE in_object_id = XXX 
   AND a.bb_id =YY 
   AND b.bb_id =YY 

enter image description here

ИЛИ?

Другой вариант ..?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2011

Начнем с того, что ваши запросы практически не похожи!

SELECT object_id, f, length , object_bb_freq as C
FROM (select object_id, f, length
      from bb_index use index (in_obj_key)
      where bb_id = 14 and in_object_id = XXX) as a
join obj_bb_relation as b
     using (object_id)

SELECT object_id, f, length, object_bb_f AS C
FROM bb_index AS a
JOIN obj_bb_relation AS b
     USING ( object_id )
WHERE in_object_id = XXX AND a.bb_id =YY AND b.bb_id =YY 

В переводе пропали очень важные биты, а именно

  • Принудительный индекс для bb_index
  • Фильтр на b.bb_id

Кроме этого, поскольку вы использовали форму ANSI INNER JOIN, а не форму запятой (FROM bb_index, obj_bb_relation WHERE ..), MySQL будетпри необходимости перемешивайте предложения WHERE и ON / USING, так как они семантически являются одним и тем же.Это независимо от того, что вы подзапрашивали a, потому что MySQL достаточно умен, чтобы развернуть его.

Лично, поскольку у вас есть фильтры как для a.bb_id, так и для b.bb_id, если вы точно знали, чтоодна таблица вернула бы только 1% записей другой таблицы, тогда вы могли бы использовать часто-кавычки (FROM bb_index, obj_bb_relation WHERE ..), потому что MySQL будет обрабатывать фильтры на bb_index до присоединения к obj_bb_relation - иначе я обычноиспользуйте сплющенную форму JOIN (вариант 2), потому что она намного понятнее (чем подзапрос в варианте 1)

0 голосов
/ 02 апреля 2011

В большинстве случаев оба одинаковы. Большинство систем баз данных в настоящее время имеют оптимизацию запросов, которая автоматически выполняется из запроса 2, запроса 1. Или даже чего-то лучшего. Но если вы используете очень старую или упрощенную базу данных, вариант 1 лучше. За исключением некоторых очень особых случаев, соединения должны идти последними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...