Проверьте статистику SQL Server - PullRequest
0 голосов
/ 15 марта 2019

Из моего приложения ASP.NET, использующего EF Core, я получаю запрос к базе данных, которая содержит довольно много соединений (13). Когда я его выполняю, это работает - но на это уходит 25 секунд.

Однако, когда я использую «Legacy Cardinality Estimate» в опциях базы данных, выполнение происходит мгновенно. Как я понимаю, оценка мощности выполняется на основе статистики, поэтому я выполнил exec sp_updatestats. Хотя однажды это помогло на том же БД (но другой запрос), на этот раз это не так.

Поэтому первый вопрос, который мне приходит в голову: как мне проверить правильность статистики? И если они таковы, то почему оценщик кардинальности сделает неправильный выбор?

Или в более общем плане: как мне подойти к этой проблеме, не прибегая к вышеупомянутой опции (включение чего-то устаревшего не звучит правильно)?

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

К сожалению, когда дело доходит до СЕ, все сходится. Вы сказали это сами. 25 секунд против <1 секунды, и оба использовали одну и ту же статистику, обновленную или нет, одни и те же индексы, один и тот же запрос и так далее. Я много работал над выбором CE, и оказалось, что (после статистики, индексов и всех стандартных рекомендуемых действий) один оценщик может работать очень хорошо, а другой - очень плохо. И это может быть по одному и тому же запросу с 1 разницей в фильтрах или 2 различными запросами, дающими точно одинаковые результаты. В большинстве случаев оба работают хорошо или приемлемо. Иногда, однако, 1 из них всего испортить. Там вы должны либо использовать устаревшую версию CE 2012, либо заявить о себе как о «CE 2014 friendly». </p>

Или, если ваши утверждения имеют четкую идентификацию в вашем коде, а это, например, «mystatementA021», вы можете сохранить собственную статистику и выбрать CE 2012 или 2014. Но это более длинная история.

0 голосов
/ 15 марта 2019

хорошее начало для проверки - это индексы rowcnt / row. Обычно вы можете увидеть проблему здесь, хотя ее можно исправить, обновив статистику или получив последнюю версию CU (накопительное обновление) или SP (пакет обновления), и даже в этом случае она еще не может быть исправлена.

У меня была эта проблема в 2014 году sp2 и sp3, только пакеты обновления не исправили оценку мощности. Вам необходимо получить последнее Накопительное обновление.

declare 
     @table_name varchar(128) = 'TableName'
    ,@schema_name varchar(128) = 'dbo'

/* 2014 and after I believe */
select max(p.rows) rows from sys.tables t 
inner join sys.indexes i on t.object_id = i.object_id
inner join sys.partitions p on t.object_id = p.object_id and p.index_id = i.index_id -- current-ish
where t.name = @table_name and schema_name(t.schema_id) = @schema_name

/* 2008 to 2012 I believe */
select max(i.rows)
from sys.tables t
inner join sys.sysindexes i on i.id = t.object_id -- the old dbo.sysindexes becomes a view
where t.name = @table_name and schema_name(t.schema_id) = @schema_name

/* 2000 and possibly earlier */
select max(i.rows)
from sys.tables t
inner join dbo.sysindexes i on i.id = t.object_id -- a real live table, still selectable
where t.name = @table_name and schema_name(t.schema_id) = @schema_name

...