Когда оптимизация sql становится излишней? - PullRequest
3 голосов
/ 15 января 2010

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

Например, если я знаю, что хочу установить столбец на 3, я мог бы использовать этот запрос:

update mytable set col = 3

Или я могу обновить запись, только если она другая

update mytable set col = 3 where col <> 3

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

update mytable set col = 3 where col <> 3 and createDate > @lastRunDate

И, возможно, я мог бы поискать больше вещей в дополнительных столбцах.

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

Обновление

Итак, вот принцип, который я пытаюсь соединить на основе сказанного. Не стесняйтесь спорить с этим, и я обновлю его соответственно:

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

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

  3. Если у вас есть смесь индексированных и неиндексированных столбцов, определенно используйте индексированные столбцы, если можете, и только неиндексированные столбцы, если ... [[Я все еще борюсь с этой частью. Какой порог для введения неиндексированных столбцов в предложении where?]]

Обновление № 2 Похоже, у меня есть свой ответ.

Ответы [ 2 ]

6 голосов
/ 15 января 2010

Если у вас есть индекс «col», то при выполнении вашего первого запроса обновится миллионы строк независимо; Ваш второй запрос потенциально обновит только несколько и быстро их найдет, если будет доступен индекс. Если у вас нет индекса для этого столбца, эффект будет незначительным, поскольку необходимо выполнить полное сканирование таблицы или индекса, чтобы проверить все строки в вашей таблице (у вас будет меньше фактических обновлений, но это так).

Весь смысл ограничения ваших запросов с помощью предложений WHERE состоит в том, чтобы уменьшить объем вашего запроса, например. количество строк, на которые должен смотреть SQL Server. Меньше данных для обработки - всегда быстрее, чем просто делать это для всех миллионов строк ......

В ответ на ваше обновление : основная цель использования предложения WHERE - сократить количество строк, которые необходимо проверить / коснуться. Если у вас есть средство (обычно индекс), чтобы уменьшить это число со 100% до нескольких процентов, то это определенно стоит того. В этом весь смысл наличия индексов (в основном для SELECT, но, разумеется, относится и к другим операциям).

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

Очевидно, что существует точка, в которой еще один критерий или индекс больше не помогают. Если это так, то, как правило, еще одно предложение WHERE не очень поможет - или вообще не поможет. Но в этом случае оптимизатор SQL-запросов найдет эти случаи и отфильтрует их (возможно, даже просто игнорируя их при выборе наилучшего плана выполнения запроса).

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

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

Добавление индексированных полей к предложению where часто сокращает время запроса, однако добавление неиндексированных полей может привести к сканированию таблицы, что замедлит ваш запрос.

Мое предложение - написать работающий запрос, посмотреть на время выполнения, поработать, чтобы уменьшить его до приемлемого уровня, посмотрев на план запроса. Не переусердствуйте, ищите приемлемое решение.

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