Какой оператор SQL быстрее? - PullRequest
1 голос
/ 28 октября 2008

Какой оператор 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 строки из каждой таблицы, чтобы периодически создавать сводку. Какое утверждение быстрее?

Ответы [ 11 ]

11 голосов
/ 28 октября 2008

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

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

5 голосов
/ 28 октября 2008

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

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

4 голосов
/ 28 октября 2008

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

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

1 голос
/ 29 октября 2008

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

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

0 голосов
/ 29 октября 2008

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

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

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

0 голосов
/ 29 октября 2008

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

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

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

0 голосов
/ 28 октября 2008

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

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

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

0 голосов
/ 28 октября 2008

Спасибо за ответы, ребята.

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

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

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

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

0 голосов
/ 28 октября 2008

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

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

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

0 голосов
/ 28 октября 2008

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

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

Например:

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';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...