2015-06-11 4 views
0

Я использую SQL Server 2008 R2 и у меня есть две базы данных, которая одна имеет 11.000 запись, а другой только 3000 запись, когда я делаю запустить этот запросПочему мой запрос sql настолько медленный в одной базе данных?

SELECT Right(rtrim(tbltransac.No_Faktur),6) as NoUrut, 
     tbltransac.No_Faktur, 
     tbltransac.No_FakturP, 
     tbltransac.Kd_Plg, 
     Tblcust.Nm_Plg, 
     GRANDTOTAL AS Total_Faktur, 
     tbltransac.Nm_Pajak, 
     tbltransac.Tgl_Faktur, 
     tbltransac.Tgl_FakturP, 
     tbltransac.Total_Distribusi 
FROM Tblcust 
    INNER JOIN ViewGrandtotal AS tbltransac ON Tblcust.Kd_Plg = tbltransac.Kd_Plg 
WHERE tbltransac.Kd_Trn = 'J' 
    and year(tbltransac.tgl_faktur)=2015 
    And ISNULL(tbltransac.No_OPJ,'') <> 'SHOP' 
Order by Right(rtrim(tbltransac.No_Faktur),6) Desc 

Он берет меня 1 минута 30 секунд в моей server (я запрашиваю его с помощью инструмента управления sql), у которого есть 3000 записей, но для выполнения запроса на моем другом сервере потребовалось всего 3 секунды, у которого есть 11000 записей, что же касается моей базы данных?

Я уже пытался создать резервную копию и восстановить мою базу данных 3000 записей и восстановить ее на своем сервере записи 11000. Это быстрее .. потребовалось 30 секунд для выполнения запроса, но это все еще раздражает, если я сравниваю с моим 11000-сервером записи , Они в той же спецификации

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

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

+0

ли индексы идентичны? – Kris

+0

_year (tbltransac.tgl_faktur) = 2015_, и ваш заказ не работает с индексом, потому что у вас есть функция в этом заявлении. –

+0

да, это одна и та же база данных, только разные магазины, которые используют ее –

ответ

1

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

Подобно тому, как, например, изменить запрос к этому:

SELECT Right(rtrim(tbltransac.No_Faktur),6) as NoUrut, 
     tbltransac.No_Faktur, 
     tbltransac.No_FakturP, 
     tbltransac.Kd_Plg, 
     Tblcust.Nm_Plg, 
     GRANDTOTAL AS Total_Faktur, 
     tbltransac.Nm_Pajak, 
     tbltransac.Tgl_Faktur, 
     tbltransac.Tgl_FakturP, 
     tbltransac.Total_Distribusi 
FROM Tblcust 
    INNER JOIN ViewGrandtotal AS tbltransac ON Tblcust.Kd_Plg = tbltransac.Kd_Plg 
WHERE tbltransac.Kd_Trn = 'J' 
    and tbltransac.tgl_faktur BETWEEN '20150101' AND '20151231' 
    And tbltransac.No_OPJ <> 'SHOP' 
Order by NoUrut Desc --Only if you need a sorted output in the datalayer 

Еще одна идея, если ваш viewGrandTotal довольно большой, может быть предварительной фильтрации этой таблицы, прежде чем присоединиться к нему. Иногда SQL Server не получает хорошего плана, который нуждается в прекрасном прикосновении, чтобы заставить его в правильном направлении.

Может быть, это:

SELECT Right(rtrim(vgt.No_Faktur),6) as NoUrut, 
     vgt.No_Faktur, 
     vgt.No_FakturP, 
     vgt.Kd_Plg, 
     tc.Nm_Plg, 
     vgt.Total_Faktur, 
     vgt.Nm_Pajak, 
     vgt.Tgl_Faktur, 
     vgt.Tgl_FakturP, 
     vgt.Total_Distribusi 
FROM (SELECT Kd_Plg, Nm_Plg FROM Tblcust GROUP BY Kd_Plg, Nm_Plg) as tc -- Pre-Filter on just the needed columns and distinctive. 
INNER JOIN (
     -- Pre filter viewGrandTotal 
     SELECT DISTINCT vgt.No_Faktur, vgt.No_Faktur, vgt.No_FakturP, vgt.Kd_Plg, vgt.GRANDTOTAL AS Total_Faktur, vgt.Nm_Pajak, 
       vgt.Tgl_Faktur, vgt.Tgl_FakturP, vgt.Total_Distribusi 
     FROM ViewGrandtotal AS vgt 
     WHERE tbltransac.Kd_Trn = 'J' 
     and tbltransac.tgl_faktur BETWEEN '20150101' AND '20151231' 
     And tbltransac.No_OPJ <> 'SHOP' 
    ) as vgt 
    ON tc.Kd_Plg = vgt.Kd_Plg 
Order by NoUrut Desc --Only if you need a sorted output in the datalayer 

Предварительная фильтрация может увеличить выработку лучшего плана.

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

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

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

С наилучшими пожеланиями, Ионных

+0

благодарю вас, я так отчаянно хочу найти, что произошло, когда я попробую ваш запрос, мое время запроса уменьшится на 20 секунд, ghosss ..thank u again ionic –

+0

Приятно здесь, что решение сработало для вас. :-) Возможно, это может быть немного изменено, но это просто можно обрабатывать с реальными данными в фоновом режиме. Возможно, какой-то показатель может быть полезен для вас. – Ionic

1

Примечание: первую очередь следует избегать какой-либо функции в Где положение как этот

year(tbltransac.tgl_faktur)=2015 

HereAaron Bertrand, как работать с датой в Где пункт

«Для того, чтобы наилучшим образом использовать индексы, и, чтобы избежать захвата слишком мало или слишком много строк, наилучшим способом для достижения выше запрос является «:

SELECT COUNT(*) 
     FROM dbo.SomeLogTable 
     WHERE DateColumn >= '20091011' 
     AND DateColumn < '20091012'; 

И я не могу понять логику в этой части кода, но это плохая часть вашего запроса слишком

ISNULL(tbltransac.No_OPJ,'') <> 'SHOP' 

на самом деле Null <> "Shop" в этом случае, так почему вы заменяете его на ""?

Спасибо и удачи

1

Вот некоторые рекомендации:

  1. year(tbltransac.tgl_faktur)=2015 заменить это tbltransac.tgl_faktur >= '20150101' and tbltransac.tgl_faktur < '20160101'

  2. ISNULL(tbltransac.No_OPJ,'') <> 'SHOP' заменить это tbltransac.No_OPJ <> 'SHOP' потому NULL <> 'SHOP'.

  3. Order by Right(rtrim(tbltransac.No_Faktur),6) Desc удалите это, потому что заказ должен выполняться в слое представления, а не в слое данных.

Читайте о SARG аргументы и предикаты:

What makes a SQL statement sargable?

Чтобы написать соответствующее SARG, вы должны убедиться, что столбец, который имеет индекс на нем в предикате появляется одна, не как функция параметр. SARG должны иметь форму столбца inclusive_operator или inclusive_operator. Имя колонки равно одному с одной стороны выражения, а с другой стороны появляется постоянное или вычисленное значение . Включительные операторы включают операторов =,>, <, =>, < =, МЕЖДУ И НРАВИТСЯ. Однако LIKE оператор включено, только если вы не используете подстановочные% или _ в начале строка, которую вы сравниваете столбец

Смежные вопросы