2008-10-28 3 views
1

Какой оператор SQL быстрее?Какой оператор SQL работает быстрее?

SELECT TOP 2 c1.Price, c2.Price, ..... c49.Price, c50.Price 
FROM Table1 AS c1, Table2 AS c2, ..... Table49 AS c49, Table50 AS c50 
WHERE c1.Date = c2.Date AND c2.Date = c3.Date ..... c49.Date = c50.Date 
ORDER BY c1.ID DESC 

     OR 

SELECT TOP 2 c1.Price, c2.Price, ..... c49.Price, c50.Price 
FROM (Table1 AS c1 
INNER JOIN (Table2 AS c2 
    ........ 
    INNER JOIN (Table49 AS c49 
    INNER JOIN Table50 AS c50 
    ON c49.Date = c50.Date) 
    ........ 
ON c2.FullDate__ = c3.FullDate__) 
ON c1.FullDate__ = c2.FullDate__) 
ORDER BY c1.ID DESC"; 

В основном мне нужно извлечь 2 строки из каждой таблицы, чтобы периодически создавать сводки. Какое утверждение выполняется быстрее?

+0

Какой SQL-сервер вы используете? – 2008-10-28 09:56:38

+0

Что происходит с этими брекетами? Почему это не «соединять таблицу2 на c1.FullDate = c2.FullDate» и т. Д. ... – 2008-10-28 11:16:59

+0

Хммм, раньше не замечал этих внутренних комментариев. Довольно круто. В любом случае я использую MS Access для прототипа, но я сейчас перехожу к MySQL (см. Мой более ранний ответ), и эти скобки необходимы, иначе запрос не будет выполнен. – user32012 2008-10-28 22:46:53

ответ

11

Для чего быстрее нет 50 столов. Присоединение к 50 столам может быть в порядке, но это очень противоречивый дизайн и, вероятно, не самое удобное решение.

Можете ли вы хранить свои данные в строках (или столбцах) из одной (или меньше) таблиц, а не из 50 таблиц?!

5

ГДЕ обычно лучше, но лучший способ от случая к случаю и выбросить это в профайлер, или проще все же отображения плана выполнения. У людей часто есть очень сильные мнения о том, какой подход является самым быстрым/лучшим в теории, но нет никакой замены для фактической настройки в соответствии с данными, которые вы на самом деле имеете в виду, поскольку применимые изменения теории зависят от вашей загрузки данных.

Если у вас еще нет реальных данных, попробуйте создать реалистичные данные о стрессе. Это будет по-прежнему полезно для тестирования. Затем планируйте время для настройки, когда приложение активно.

-8

Игнорируйте СОБЫТИЯ, когда это возможно. Производительность мудрая, утверждения Join неэффективны вообще.

+0

Предложение where также выполняет «соединение», но без использования ключевого слова join. Устранение сбоев по соображениям производительности выполняется на этапе проектирования модели базы данных, не денормализуя определенные части вашей модели. – Ruben 2008-10-28 10:06:43

+0

Этот ответ на 100% ошибочен. С правильными индексами JOINs очень эффективны. – 2008-10-28 11:10:49

3

Возможно, вы обнаружите, что механизм оптимизации SQL будет генерировать один и тот же внутренний запрос (если логика будет одинаковой), и в результате не будет никакой разницы.

Как упоминалось другими, запустите это через профайлер (например, анализатор запросов), чтобы определить разницу (если таковая имеется).

0

Обычно база данных оптимизирует оба утверждения, поэтому разница не будет такой большой. Но вы можете проверить это, составив план объяснения для обоих запросов.

Одна вещь, которая могла бы оптимизировать запрос с помощью объединений (я еще не проверял это), заключается в наличии дополнительных ограничений (ограничений на объединение) в операторе объединения. Хотя это не рекомендуется, так как он явно не разделяет условия соединения и другие условия.

Например:

select *  
    from A a 
     join B b on b.x = a.y  
     where b.z = 'ok'; 

можно записать в виде

select * 
    from A a 
     join B b on b.x = a.y and b.z = 'ok'; 
0

Если вы приложите снимок экрана ваших планов запросов и Profiler след я буду рад сообщить вам, что быстрее , На самом деле информации недостаточно, чтобы ответить на вопрос иначе.

Я чувствую, что оба имеют очень схожую производительность в SQL Server и что SQL-сервер оптимизирует как использование одного и того же плана запросов, но кто знает, возможно ли объединение в пятьдесят таблиц делает оптимизатора немного сумасшедшим.

В целом я придерживаюсь семантики JOIN, потому что мне легче ее читать и поддерживать. Крест-соединение очень подвержено ошибкам и крайне редко.

0

Благодарим за ответы ребятам.

У меня нет доступа к Query Analyzer, так как я в настоящее время перемещаю эту базу данных с MS Access, где я делал быстрый прототип, в MySQL. Я считаю, что Query Analyzer - , доступный только на SQL Server, но я могу ошибаться, поэтому я не могу прикрепить свою трассировку Profiler.

Каждая таблица различна (т. Е. Значения в ней уникальны, хотя имена столбцов могут быть одинаковыми) и используются отдельно для генерации других объектов, но мне нужно иногда запускать сводку, которая собирает строки из каждой таблицы. Итак, я считаю, что мне нужно 50 столов, хотя я не конкретизировал всю схему вещей и поэтому буду изучать ее. (стр. Я новичок в базах данных и SQL, но не новичок в программировании). Мне также нужно рассмотреть разброс по размеру памяти, если я должен был поместить всю информацию в одну таблицу, когда будет использоваться только небольшая часть.

Однако, из того, что я собрал, разница не должна быть такой важной, поскольку 2 утверждения, вероятно, будут скомпилированы в один и тот же внутренний запрос. Я задал вопрос, желая узнать, будут ли внутренние детали разными. Будут проверять фактические данные, чтобы узнать.

Кстати, будет ли производительность на 2-х утверждениях иметь значение, если мы, хотя бы, в уравнения параллельных запросов несколькими пользователями?

0

Вы не указываете ожидаемый объем своих таблиц, но имейте в виду, что если запросы оптимизируются для разных планов запросов, то то, что является самым быстрым из 100 строк в вашей таблице, может быть не таким, как если у вас есть 100 000 строк или более.

На самом деле, как правило, мало что можно получить от навязчивой оптимизации запросов, используя таблицы менее 10 000 записей, если у вас разумно продуманные индексы и запросы. Однако где-то около 100 000 записей производительность плохо оптимизированных запросов начнет ухудшаться, как правило, катастрофически. Точная цифра зависит от размера строки и объема памяти, имеющейся у вас на сервере, но это не редкость, когда производительность ухудшается на порядок или больше для удвоения размера таблицы.

Как правило, лучшая стратегия не тратить время на небольшие запросы на меньшие таблицы, усилия обычно могут быть потрачены более выгодно в другом месте. Однако агрессивно оптимизируйте любые запросы, которые выполняются против вас, основные таблицы, если ожидается, что они вырастут более 10 000 строк. Обычно это будет означать использование экземпляра QA и загрузку с 10-кратным ожидаемым объемом для проверки фактического поведения.

1

Все разговоры о том, чтобы иметь меньше таблиц, заставили меня задуматься (спасибо MarkR). Я был , проходящий через документацию MySQL за последние пару часов, и понял , что лучшим решением было бы создать новую сводную таблицу, которая проведет начальные результаты . После этого я создавал бы триггер, который обновлял новую таблицу всякий раз, когда вставка происходит на одной из таблиц, которые всегда касаются.

Еще одна идея, о которой я думал, это создание представления запроса. Однако кажется, что MySQL запускает основной запрос к просмотру каждый раз, когда он вызывается. Я прав? Есть ли способ , чтобы заставить MySQL хранить результирующую таблицу предварительно выполненного представления, а затем использовать триггер , чтобы сообщить, когда нужно обновить таблицу? Есть ли какая-нибудь СУБД, которая это делает?

0

Оптимизация заказа на соединение занимает экспоненциальное время. Каждый механизм базы данных просто выбирает небольшое количество возможных заказов на соединение и оценивает лучший из них.

Кажется, что вы всегда будете хотеть join ... on c*1*.Date = c*n*.Date для всех n.

Вы также захотите избавиться от чрезвычайно необычной схемы базы данных, которую у вас есть.

0

Что случилось, когда вы попробовали?

Я имею в виду серьезно, Query Analyzer имеет небольшой таймер по причине. Различные структуры запросов иногда дают совершенно разные времена исполнения, часто без интуитивной причины.

Напишите оба вопроса. Проверьте их. Затем вернитесь и ответьте на свой вопрос.