Находится SQL В плохо для производительности?

Когда вы изменяете переключатель планировщика на «вкл» для группы обеспечения доступности баз данных, планировщик запускает обратную засыпку всех экземпляров прогона dag, для которых у него нет записанного статуса, начиная с даты start_date, которую вы указали в «default_args».

Например: если начальная дата была «2017-01-21», а вы включили переключатель планирования на «2017-01-22T00: 00: 00», и ваш dag был настроен на ежечасную работу, то планировщик будет выполняется обратная засыпка 24 дня, а затем запускается с запланированным интервалом.

Это, по сути, то, что происходит в обоих ваших вопросах. В # 1 он заполняет 3 пропущенных прогона из 30 секунд, которые вы выключили планировщик. В # 2 он заполняет все прогоны DAG от start_date до «сейчас».

Существует два способа решения этой проблемы:

  1. Установите для start_date дату в будущем, чтобы он начинал планировать запуски dag только по достижении этой даты. Обратите внимание, что если вы измените начальную дату DAG, вы должны также изменить имя DAG из-за того, как дата начала хранится в базе данных воздушного потока.
  2. Вручную запустите обратную засыпку из командной строки с флагом «-m», который говорит воздушному потоку не запускать DAG, а просто пометить его как успешный в БД ( https: //airflow.incubator .apache.org / cli.html ).

    например. airflow backfill MY_tutorial -m -s 2016-10-04 -e 2017-01-22T14:28:30

60
задан Developer 22 January 2015 в 11:25
поделиться

13 ответов

При написании запроса с использованием оператора IN следует учитывать несколько факторов, которые могут повлиять на производительность.

Во-первых, В большинстве баз данных предложения IN обычно внутренне переписываются для использования логической связки OR. Итак, col IN ('a', 'b', 'c') заменяется на: (COL = 'a') OR (COL = 'b') or (COL = 'c ') . План выполнения для обоих запросов будет , вероятно, будет эквивалентным, если у вас есть индекс на col .

Во-вторых, при использовании IN или OR с переменным числом аргументов вы заставляют базу данных повторно анализировать запрос и перестраивать план выполнения при каждом изменении аргументов. Построение плана выполнения запроса может быть дорогостоящим шагом. Большинство баз данных кэшируют планы выполнения для запросов, которые они запускают, используя ТОЧНЫЙ текст запроса в качестве ключа. Если вы выполните аналогичный запрос, но с другими значениями аргументов в предикате, вы, скорее всего, заставите базу данных потратить значительное количество времени на синтаксический анализ и построение планов выполнения. Вот почему связываемые переменные настоятельно рекомендуются как способ обеспечения оптимальной производительности запросов.

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

В-четвертых, запросы, которые включают в себя IN и OR в предикате, не всегда могут быть оптимально переписаны в параллельной среде. Существуют различные случаи, когда оптимизация параллельного сервера не применяется - MSDN имеет достойное введение в оптимизацию запросов для параллелизма. Однако, как правило, запросы, использующие оператор UNION ALL, тривиально распараллеливаются в большинстве баз данных - и по возможности предпочтительнее логических связок (например, OR и IN).

запросы, содержащие IN и OR в предикате, не всегда могут быть оптимально переписаны в параллельной среде. Существуют различные случаи, когда оптимизация параллельного сервера не применяется - MSDN имеет достойное введение в оптимизацию запросов для параллелизма. Однако, как правило, запросы, использующие оператор UNION ALL, тривиально распараллеливаются в большинстве баз данных - и по возможности предпочтительнее логических связок (например, OR и IN).

запросы, содержащие IN и OR в предикате, не всегда могут быть оптимально переписаны в параллельной среде. Существуют различные случаи, когда оптимизация параллельного сервера не применяется - MSDN имеет достойное введение в оптимизацию запросов для параллелизма. Однако, как правило, запросы, использующие оператор UNION ALL, тривиально распараллеливаются в большинстве баз данных - и по возможности предпочтительнее логических связок (например, OR и IN).

121
ответ дан 24 November 2019 в 17:37
поделиться

Если у вас есть хороший индекс на FieldW, использование этого IN является совершенно правильным.

Я только что протестировал, и SQL 2000 выполняет сканирование кластерного индекса при использовании IN.

5
ответ дан 24 November 2019 в 17:37
поделиться

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

AFAIK, SQL Server 2000 не может построить хеш-таблицу набора констант, что лишает оптимизатор возможности использовать HASH SEMI JOIN .

Это поможет, только если у вас нет индекса для FieldW (который у вас должен быть).

Вы также можете попробовать включить столбцы FieldX и FieldY в индекс:

CREATE INDEX ix_a_wxy ON a (FieldW, FieldX, FieldY)

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

SQL Server 2000 не имеет опции INCLUDE для CREATE INDEX , и это может немного ухудшить производительность DML но улучшить производительность запросов.

Обновление:

Из вашего плана выполнения я вижу, что вам нужен составной индекс на (SettingsID, SectionID)

SQL Server 2000 действительно может построить хеш-таблицу из списка констант (и делает это), но Hash Semi Join , скорее всего, будет менее эффективным, чем Nested Loop для запроса запроса.

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

A COUNT (столбец) ] не учитываются строки, для которых значение столбца равно NULL .

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

Поскольку ThreadId похоже на КЛАСТЕРНЫЙ ПЕРВИЧНЫЙ КЛЮЧ , он подходит для этого самого запроса, но старайтесь избегать его в целом.

5
ответ дан 24 November 2019 в 17:37
поделиться

В зависимости от распределения данных дополнительные предикаты в предложении WHERE могут повысить производительность. Например, если набор идентификаторов невелик по сравнению с общим числом в таблице, и вы знаете, что идентификаторы относительно близки друг к другу (возможно, они обычно являются недавними добавками и, следовательно, сгруппированы в верхнем конце диапазона), вы можете попробовать включить предикат «И FieldW МЕЖДУ 109 И 891» (после определения минимального и максимального идентификаторов в вашем наборе в коде C #). Возможно, сканирование диапазона для этих столбцов (если они проиндексированы) работает быстрее, чем то, что используется в настоящее время.

3
ответ дан 24 November 2019 в 17:37
поделиться

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

Давайте начнем с плана запроса для запроса, срок ожидания которого истекает. Вы точно знаете, какой это запрос?

3
ответ дан 24 November 2019 в 17:37
поделиться

Обычно предложение IN вредно для производительности, но то, что «плохо», зависит от приложения, данных, размера базы данных и т. Д. Вам необходимо протестировать собственное приложение, чтобы увидеть, что лучше.

1
ответ дан 24 November 2019 в 17:37
поделиться

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

2
ответ дан 24 November 2019 в 17:37
поделиться

В основном то, что делает это предложение where, это «FieldW = 108 OR FieldW = 109 OR FieldW = 113 ...». Иногда можно повысить производительность, выполняя множественный выбор и комбинируя их с помощью объединения. Например:

SELECT FieldX, FieldY FROM A WHERE FieldW = 108
UNION ALL
SELECT FieldX, FieldY FROM A WHERE FieldW = 109

Но, конечно, это непрактично, когда вы сравниваете так много значений.

Другой вариант - вставить эти значения во временную таблицу, а затем присоединить таблицу A к этой временной таблице.

1
ответ дан 24 November 2019 в 17:37
поделиться

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

1
ответ дан 24 November 2019 в 17:37
поделиться

О производительности можно судить только в контексте того, что вы пытаетесь сделать. В этом случае вы запрашиваете извлечение около 70 строк (при условии, что это уникальные значения), поэтому вы можете ожидать примерно в 70 раз больше продолжительности извлечения одного значения. Это может быть меньше из-за кеширования или конечно.

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

0
ответ дан 24 November 2019 в 17:37
поделиться

Вот ваш ответ ...

http://www.4guysfromrolla.com /webtech/031004-1.shtml

По сути, вы хотите создать функцию, которая разделит строку и заполнит временную таблицу разделенным содержимым. Затем вы можете присоединиться к этой временной таблице и управлять своими данными. Вышеупомянутое довольно хорошо объясняет. Я много использую эту технику.

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

Вышеупомянутое довольно хорошо объясняет. Я много использую эту технику.

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

Вышеупомянутое довольно хорошо объясняет. Я много использую эту технику.

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

1
ответ дан 24 November 2019 в 17:37
поделиться

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

В ваш случай: Кажется, не так уж и плохо.

0
ответ дан 24 November 2019 в 17:37
поделиться

Вы можете попробовать что-то вроде:

select a.FieldX, a.FieldY
from (
    select FieldW = 108 union
    select FieldW = 109 union
    select FieldW = 113 union
    ...
    select FieldW = 891
) _a
join A a on a.FieldW = _a.FieldW

Это может быть подходящим для вашей ситуации, например, когда вы хотите динамически сгенерировать один оператор SQL. На моей машине (SQL Server 2008 Express) при тестировании с небольшим количеством (5) значений FieldW и большим количеством (100000) строк в A используется поиск по индексу в A с соединением вложенных циклов между A и _a, что, вероятно, именно то, что вы ищете.

0
ответ дан 24 November 2019 в 17:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: