Является ли преждевременная оптимизация в SQL такой же «злой», как в процедурных языках программирования? - PullRequest
4 голосов
/ 15 февраля 2010

В данный момент я изучаю SQL и прочитал, что объединения и подзапросы потенциально могут снизить производительность. Я (немного) знаю теорию об алгоритмической сложности в процедурных языках программирования и стараюсь помнить об этом при программировании, но я не знаю, насколько дорогими могут быть различные запросы SQL. Я решаю, стоит ли мне тратить время на изучение производительности SQL или просто замечать это, когда мои запросы работают медленно. Тогда основной вопрос для меня таков: является ли преждевременная оптимизация для SQL такой же злой, как и для процедурных языков?

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

Вот цитата Дональда Кнута, на которую я ссылаюсь, когда говорю «зло»:

Мы должны забыть о маленьких эффективность, скажем, около 97% время: преждевременная оптимизация корень всех зол. Все же мы не должны упустить наши возможности в этом критический 3%.

Ответы [ 6 ]

3 голосов
/ 15 февраля 2010

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

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

Но вы не должны иметь производительность в качестве первой цели: во-первых, это приложение, которое работает; и затем, при необходимости, вы оптимизируете его (имея некоторые понятия о производительности при разработке, вы получите приложение, которое проще оптимизировать) .

Примечание. Я бы не сказал, что "иметь представление о производительности" - это "преждевременная оптимизация" , если вы не просто "оптимизируете", но просто «напишите правильно» ; Я бы скорее назвал это хорошей практикой, которая поможет писать код лучшего качества; -)

2 голосов
/ 15 февраля 2010

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

В 3% случаев, когда вам нужна высокая производительность, важно знать, какие правила нарушать и почему.

Однако, в отличие от процедурных языков, даже для строк размером 150 тыс. Может быть важно знать немного о том, как обрабатывается ваш запрос. Например, поиск свободного текста будет очень медленным по сравнению с поиском по точным совпадениям в индексированных столбцах. Это делает последние шаги, например, шардинг или полная денормализация, где большинство администраторов баз данных и разработчиков проводят черту.

1 голос
/ 15 февраля 2010

Кнут говорит, что «забудьте о 97%», но для типичного веб-приложения он находится в базе данных ввода-вывода, где тратится 97% времени запроса. Здесь небольшие усилия по оптимизации могут дать наибольшие результаты.

Если вы пишете такие приложения, я настоятельно рекомендую изучить как можно больше работы с СУРБД. Другие люди дают вам отличные предложения, и я бы добавил, что я обычно следую этому списку сверху вниз, когда решаю, как потратить свой «бюджет на оптимизацию»:

  1. Схема проектирования. Подумай двенадцать раз о нормализации и доступе стратегии. Это спасет вас много болезненные часы спустя.

  2. Читаемость запроса. Относится к # 1, иногда пытаясь реорганизовать ваш запросы дают лучшее понимание как схема должна выглядеть. Также это будет помочь позже, когда вы попросите помощь.

  3. Избегайте подзапросов в списке SELECT, используйте JOIN и.

  4. Если медленные запросы достигают Profiler. Проверьте на отсутствие индексов И наконец, если есть все еще медленные запросы, попробуйте переписать это.

Имейте также в виду, что производительность базы данных очень сильно зависит от распределения данных и количества одновременных запросов (из-за блокировки). Даже если запрос завершается за 1 сек. на вашем слабом нетбуке это может занять 15 секунд на 8-ядерном сервере. Если возможно, проверьте ваши запросы на фактические данные. Если вы знаете, что уровень параллелизма будет высоким, (как это ни парадоксально) лучше использовать много маленьких запросов, чем один большой.

1 голос
/ 15 февраля 2010

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

Я лично профилирую свои запросы и сосредотачиваюсь на худших и наиболее часто используемых запросах. Тщательный дизайн заблаговременно избавляет от худшего.

1 голос
/ 15 февраля 2010

Я бы сказал, что вы должны сделать SQL настолько легко читаемым, насколько это возможно, и беспокоиться о производительности только после того, как он достигнет вас.

Это сказал.

Будьте внимательны со стандартными вещами, которые вы разрабатываете, такими как индексы, подвыборы, использование курсоров, когда стандартный запрос будет выполнять свою работу и т. Д.

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

EDIT

Также помните, что удобство сопровождения вашего кода SQL очень важно, и что отладка SQL немного сложнее, чем обычное кодирование.

0 голосов
/ 15 февраля 2010

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

Лично мне нравится инкапсулировать весь мой SQL в процедуры PL / SQL, но есть некоторые, кто с этим не согласен. Что бы вы ни делали, я рекомендую стараться не помещать ваш SQL "в строку" с другим исходным кодом. Кажется, что это всегда приводит к резке и вставке и быстро становится трудным в обслуживании. Поместите ваш SQL-код в другое место и постарайтесь использовать его как можно чаще.

Кроме того, ознакомьтесь с индексами, как они действительно работают, и когда вы должны и не должны их использовать. Когда люди получают медленный запрос, первым инстинктом многих людей является индексация таблицы до смерти. Это может решить проблему в краткосрочной перспективе, но в долгосрочной перспективе таблица с избыточным индексом будет медленно вставляться и обновляться. Несколько правильно подобранных индексов намного лучше, чем индексирование каждого поля. Попробуйте прочитать «Рефакторинг приложений SQL» Стефана Фарула.

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

Удачи!

...