2015-01-16 4 views
1

Два следующих ниже кода делают то же самое. В основном показывают все идентификаторы таблицы 1, которые присутствуют в таблице 2. То, что меня озадачивает, - это то, что простой выбор равен way way быстрее, чем JOIN, я бы ожидал, что JOIN немного медленнее, но не так сильно ... 5 секунд против 0,2Выбор скорости vs join

Может ли кто-нибудь уточнить это?

SELECT table1.id FROM  
table1,table2 WHERE 
table1.id=table2.id 

Продолжительность/Fetch 0,295/0,028 (MySQL Workbench 5.2.47)

SELECT table1.id 
FROM table1 
INNER JOIN table2 
ON table1.id=table2.id 

Продолжительность/Fetch 5,035/0,027 (MySQL Workbench 5.2.47)

+1

Первый использует также соединение (только устаревший синтаксис с неявными объединениями в предложении where). Поскольку оба они на 100% равны с точки зрения того, что они должны делать, я бы заподозрил здесь ошибку в MySQL. –

+1

Какой из них вы запускали первым? Что говорит EXPLAIN? – evanv

+1

Это тот же запрос. Я подозреваю, что вы смотрите на кеш – Strawberry

ответ

0

Вопрос: Может ли кто-нибудь уточнить это?

A: Перед тем, как идти «ошибка в MySQL» маршрут, который @a_horse_with_no_name кажется нетерпеливы мчаться вниз, мы действительно должны гарантировать, что это повторяемые поведение, и это не просто причуда.

И для этого нам действительно нужно увидеть результат прошедшего времени из нескольких прогонов запроса.

Если кэш запросов включен на сервере, мы хотим запустить запросы с добавлением подсказки SQL_NO_CACHE (SELECT SQL_NO_CACHE table1.id ...), чтобы мы знали, что мы не извлекаем кешированные результаты.

Я бы повторил выполнение каждого запроса по крайней мере три раза и выкинул результат из первого запуска и усреднил другие прогоны. (Цель этого заключается в том, чтобы исключить влияние данных таблицы, которые не находятся в кеше, ни буфера InnoDB, ни кеша файловой системы.)

Также запустите EXPLAIN SELECT ... для каждого запроса. И сравните планы доступа.

Если какая-либо из этих таблиц является механизмом хранения MyISAM, обратите внимание, что таблицы MyISAM подлежат блокировке с помощью операций DML; в то время как в таблице выполняется операция INSERT, UPDATE или DELETE, операторы SELECT будут заблокированы от доступа к таблице. (Но пять секунд для этого немного важны, если только они не являются действительно большими таблицами или действительно неэффективными операторами DML).

С помощью InnoDB запросы SELECT не будут блокироваться операциями DML.

Истекшее время также будет зависеть от того, что еще происходит в системе.

Но общее количество прошедшего времени включает в себя больше, чем просто время на сервере MySQL. Временное включение MySQL general_log позволит вам отображать операторы, которые фактически обрабатываются сервером.

+0

Большое спасибо за ответ, я выключу кеш и повторю оба запроса снова. , обе таблицы действительно большие, набор результатов был немного больше, чем 17000 – Degar007

0

Это похоже на то, что может быть дополнительно оптимизировано механизмом базы данных, если вы используете оба запроса в одном и том же контексте.

SQL является декларативным.Успешно объявив, что вы хотите, двигатель имеет свободное владение для реструктуризации «Как» вашего запроса, чтобы вернуть самый быстрый результат.

В ранних версиях SQL даже не было ключевого слова JOIN. Была только запятая.

В SQL существует много кодирующих конструкций, которые настоятельно заставляют одну низшую методологию работать над другой, и их следует избегать. ПРИСОЕДИНЕНИЕ не следует избегать. Что-то звучит как промах. JOIN является основным элементом SQL. Было бы стыдно всегда использовать запятые.

Существует множество факторов, которые влияют на производительность JOIN на основе вашей среды, схемы и данных. Скорее всего, ваши таблицы1 и таблица2 представляют собой крайний случай, который, возможно, прошел мимо алгоритмов оптимизации.

0

SQL_NO_CACHE работал, новые результаты:

Продолжительность/Fetch 5,065/0,027 для выбора, где и Продолжительность/Fetch 5.050/0,027 для объединения

я бы подумал, что «выберите где «было бы быстрее, но соединение было на самом деле немного быстрым. Но разница незначительна

Я хотел бы поблагодарить всех за их ответ.