SQL Server MS 2005 - хранимая процедура “спонтанно повреждается”

использовать $ slice .

db.collection.find( {}, { array_field: { $slice: -1 } } )

Редактирование: Вы можете использовать { <field>: { $elemMatch: { <query1>, <query2>, ... } } }, чтобы найти совпадение.

Но это не даст именно то, что вы ищете. Я не думаю, что это возможно в mongoDB.

8
задан MatBailie 18 June 2009 в 21:54
поделиться

8 ответов

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

WITH RECOMPILE , вероятно, будет самое быстрое исправление - используйте SET STATISTICS TIME ON , чтобы узнать, какова на самом деле стоимость перекомпиляции, прежде чем исключать ее из-под контроля.

Если это все еще неприемлемое решение, лучшим вариантом, вероятно, является попытка рефакторинга оператор вставки.

Вы не говорите, используете ли вы UNION или UNION ALL в своем операторе вставки. Я видел, как INSERT INTO с UNION приводили к некоторым странным планам запросов, особенно в версиях SQL 2005 до SP2.

  • Предложение Раджа об удалении и воссоздание целевой таблицы с SELECT INTO - это один из возможных вариантов.

  • Вы также можете попробовать выбрать каждый из три исходных запроса в свои собственные временная таблица, затем UNION эти временные таблицы вместе во вставке.

  • В качестве альтернативы вы можете попробовать комбинация этих предложений - поместить результаты объединения в временная таблица с SELECT INTO , затем вставьте из этого в цель table.

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

1
ответ дан 5 December 2019 в 21:21
поделиться

Это след анализа параметров. Да, первый шаг - попробовать RECOMPILE, хотя он не всегда работает так, как вы хотите в 2005 году.

Обновление: Я бы все равно попробовал перекомпилировать на уровне оператора INSERT, так как это может быть проблема со статистикой (о да, проверьте, что автоматическое обновление статистики включено).

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

3
ответ дан 5 December 2019 в 21:21
поделиться

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

Вы также можете использовать ] WITH RECOMPILE , если набор меняется, но план запроса больше не работает.

В SQL Server 2008 вы можете использовать функцию ОПТИМИЗАЦИЯ ДЛЯ НЕИЗВЕСТНО .

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

3
ответ дан 5 December 2019 в 21:21
поделиться

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

0
ответ дан 5 December 2019 в 21:21
поделиться

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

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

Когда ваш SP блокируется, можете ли вы выполнить вставку в table_y?

0
ответ дан 5 December 2019 в 21:21
поделиться

Есть ли у вас работа по обслуживанию индекса?

Актуальна ли ваша статистика? Один из способов узнать это - изучить предполагаемый и фактический планы запроса на предмет больших вариаций.

0
ответ дан 5 December 2019 в 21:21
поделиться

Как говорили другие, очень вероятно, что это будет незафиксированная транзакция.

Мое лучшее предположение:

Вы захотите убедиться, что table_y можно удалить полностью и быстро.

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

Еще одно примечание: попробуйте использовать усечение, если возможно. он использует меньше ресурсов, чем удаление без предложения where:

truncate table table_y

Кроме того, если в вашей СОБСТВЕННОЙ транзакции происходит ошибка, все последующие вызовы (очевидно, каждые 5 минут) "зависают", если вы не обработаете свою ошибку:

begin tran
begin try
 -- do normal stuff
end try
begin catch
 rollback
end catch
commit

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

begin tran
begin try
 -- do normal stuff
end try
begin catch
 rollback
end catch
commit

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

begin tran
begin try
 -- do normal stuff
end try
begin catch
 rollback
end catch
commit

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

0
ответ дан 5 December 2019 в 21:21
поделиться

Если вы выполняете следующие действия:

DELETE table_y
INSERT INTO table_y <3 selects unioned together>

Вы можете попробовать это вместо

DROP TABLE table_y
SELECT INTO table_y <3 selects unioned together>
0
ответ дан 5 December 2019 в 21:21
поделиться
Другие вопросы по тегам:

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