Когда вы изменяете переключатель планировщика на «вкл» для группы обеспечения доступности баз данных, планировщик запускает обратную засыпку всех экземпляров прогона dag, для которых у него нет записанного статуса, начиная с даты start_date, которую вы указали в «default_args».
Например: если начальная дата была «2017-01-21», а вы включили переключатель планирования на «2017-01-22T00: 00: 00», и ваш dag был настроен на ежечасную работу, то планировщик будет выполняется обратная засыпка 24 дня, а затем запускается с запланированным интервалом.
Это, по сути, то, что происходит в обоих ваших вопросах. В # 1 он заполняет 3 пропущенных прогона из 30 секунд, которые вы выключили планировщик. В # 2 он заполняет все прогоны DAG от start_date до «сейчас».
Существует два способа решения этой проблемы:
Вручную запустите обратную засыпку из командной строки с флагом «-m», который говорит воздушному потоку не запускать DAG, а просто пометить его как успешный в БД ( https: //airflow.incubator .apache.org / cli.html ).
например. airflow backfill MY_tutorial -m -s 2016-10-04 -e 2017-01-22T14:28:30
При написании запроса с использованием оператора 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).Если у вас есть хороший индекс на FieldW, использование этого IN является совершенно правильным.
Я только что протестировал, и SQL 2000 выполняет сканирование кластерного индекса при использовании IN.
Вы можете попробовать создать временную таблицу, вставить в нее свои значения и вместо этого использовать таблицу в предикате 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
похоже на КЛАСТЕРНЫЙ ПЕРВИЧНЫЙ КЛЮЧ
, он подходит для этого самого запроса, но старайтесь избегать его в целом.
В зависимости от распределения данных дополнительные предикаты в предложении WHERE могут повысить производительность. Например, если набор идентификаторов невелик по сравнению с общим числом в таблице, и вы знаете, что идентификаторы относительно близки друг к другу (возможно, они обычно являются недавними добавками и, следовательно, сгруппированы в верхнем конце диапазона), вы можете попробовать включить предикат «И FieldW МЕЖДУ 109 И 891» (после определения минимального и максимального идентификаторов в вашем наборе в коде C #). Возможно, сканирование диапазона для этих столбцов (если они проиндексированы) работает быстрее, чем то, что используется в настоящее время.
Есть более эффективные способы кодирования, но я сомневаюсь, что это причина ваших тайм-аутов, особенно если это только SELECT. Однако вы сможете определить это, посмотрев на трассировку вашего запроса. Но перекодирование этого было бы оптимизацией путем предположения, и притом маловероятной догадки.
Давайте начнем с плана запроса для запроса, срок ожидания которого истекает. Вы точно знаете, какой это запрос?
Обычно предложение IN вредно для производительности, но то, что «плохо», зависит от приложения, данных, размера базы данных и т. Д. Вам необходимо протестировать собственное приложение, чтобы увидеть, что лучше.
IN - это то же самое, что написать большой список OR. И OR часто делает запросы недоступными для поиска, поэтому ваши индексы могут быть проигнорированы и план идет на полное сканирование.
В основном то, что делает это предложение 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 к этой временной таблице.
размер вашей таблицы будет определять скорость при использовании этого оператора. Если это не очень большая таблица ... это утверждение не влияет на вашу производительность.
О производительности можно судить только в контексте того, что вы пытаетесь сделать. В этом случае вы запрашиваете извлечение около 70 строк (при условии, что это уникальные значения), поэтому вы можете ожидать примерно в 70 раз больше продолжительности извлечения одного значения. Это может быть меньше из-за кеширования или конечно.
Однако оптимизатору запросов может потребоваться или выбрать выполнение полного сканирования таблицы для получения значений, и в этом случае производительность будет немного отличаться от получения одного значения через тот же план доступа.
Вот ваш ответ ...
http://www.4guysfromrolla.com /webtech/031004-1.shtml
По сути, вы хотите создать функцию, которая разделит строку и заполнит временную таблицу разделенным содержимым. Затем вы можете присоединиться к этой временной таблице и управлять своими данными. Вышеупомянутое довольно хорошо объясняет. Я много использую эту технику.
В вашем конкретном случае гораздо быстрее используйте соединение с временной таблицей вместо предложения in.
Вышеупомянутое довольно хорошо объясняет. Я много использую эту технику.В вашем конкретном случае гораздо быстрее используйте соединение с временной таблицей вместо предложения in.
Вышеупомянутое довольно хорошо объясняет. Я много использую эту технику.В вашем конкретном случае гораздо быстрее используйте соединение с временной таблицей вместо предложения in.
Если вы можете использовать другие вещи, кроме IN: сделайте это (я использовал IN в некоторых случаях не очень хороший способ: я могу легко заменить существующим, и это быстрее)
В ваш случай: Кажется, не так уж и плохо.
Вы можете попробовать что-то вроде:
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, что, вероятно, именно то, что вы ищете.