2012-04-30 6 views
2

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

Эти столбцы для моей базы данных таблицы:

  • external_id
  • TimeStamp
  • Значение
  • Validation
  • Причина
  • Datum
  • Uur
  • Af ronden

Столбцы:

  • external_id является идентификатор определенного счетчика
  • Timestamp ничего не делает
  • Value является значение этого счетчика
  • Validation просто да или нет
  • Reason только что получил varchar va LUE с причиной
  • Datum дата
  • Uur в час, что это
  • Afronden столбец необходим для округления

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

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

Это мой запрос:

Declare @totaal bigInt 
Declare @tussentotaal bigint 
Declare @Datum varchar 
Declare @datumverschil varchar 
Declare @hoogste bigint 
Declare @laagste bigint 
Declare @teller bigint 
Declare @tellettotaal bigint 

set @tellettotaal = (select count(*) from cresent_opdracht_de_proost_wim.dbo.[test]) 

Set @teller = 1 

SET @datum = (Select top(1) datum 
       from cresent_opdracht_de_proost_wim.dbo.[test] 
       order by afronden asc) 

Set @datumverschil = @Datum 
set @tussentotaal = 0 
set @totaal = 0 
set @hoogste = 1775000006856 
set @laagste = 1775000006856 

while @teller <= @tellettotaal 
begin 
    if @teller = 1 
    Begin 
    set @tussentotaal = (select top(1) value 
         from cresent_opdracht_de_proost_wim.dbo.[test] 
         order by afronden asc) 

    if @tussentotaal != 0 
    begin 
     Set @tussentotaal = @tussentotaal/100 
    end 
    End 
    Else 
    begin 
    SET @tussentotaal = (Select top(1) value 
         from (select top (@teller) * 
           from cresent_opdracht_de_proost_wim.dbo.[test]) q 
         order by afronden desc) 

    Set @tussentotaal = @tussentotaal/100 
    end 

    if @tussentotaal != 0 
    Begin 
    Set @totaal = @totaal + @tussentotaal 
    end 

    SET @teller= @teller + 1 

    Set @datumverschil = (Select top(1) datum 
         from (select top (@teller) * 
           from cresent_opdracht_de_proost_wim.dbo.[test]) q 
         order by afronden desc) 

    if @datum != @datumverschil 
    Begin 
    if @totaal >= @hoogste 
    begin 
     set @hoogste = @totaal 
    end 

    if @totaal <= @laagste 
    begin 
     if @totaal != 0 
     Begin 
     set @laagste = @totaal 
     end 
    end 

    Set @datum = @datumverschil 
    set @totaal = 0 
    select @teller As teller 
    end 
end 

Select @hoogste As hoogste 
Select @laagste As laagste 

После того, как 22-й минуте были обработаны только 44000 строк.

Кто-нибудь знает, как я могу оптимизировать свой запрос?

+0

Показать MySQL, который создал эту базу данных и таблицы. В частности, покажите индексы, которые у вас есть. –

+2

Лучше не отправляйте данные примера и желаемые результаты, поэтому нам не нужно сначала выяснить, что делает ваш код RBAR. Ответ, вероятно, будет состоять в том, чтобы переписать его на основе набора. Также какая версия SQL Server? –

+0

Сначала я хотел вставить картинки, но моя репутация была недостаточно хороша, поэтому я загрузил их в Интернете. Моя база данных была создана csv, и вот что такое база данных: – Wimdp

ответ

1

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

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

ЭТО СКАЗАЛО: Я думаю, что вы можете сделать с LOT меньше запросов в целом, не запустив бессмысленную петлю поверх 1 - вместо этого получите все упорядоченное по убыванию. Брутально говоря: избавьтесь от цикла и сделайте ONE Statement, который компилирует ваш результирующий набор. Шутки в сторону. Это должно быть возможно. Не пытайтесь перехитрить оптимизатор запросов и вернуться к написанию процедурного кода базы данных, как это делали многие люди 20 лет назад во времена dbase. В целом.ваш запрос является линейным, что означает отсутствие распараллеливания, а ваше микроуправление условиями означает, что оптимизатор запросов не может быть разумным (как оптимизация - утверждение по заявлению). Определите набор результатов в одном утверждении, и вы можете задаться вопросом, насколько он эффективен.

Я уверен, что в конце вы узнаете, что вы в основном пытаетесь перехитрить что-то, что лучше, чем вы пишете запросы. Использовать SQL - определить набор результатов.

И, наконец, не зная распределения данных и - ouch - индексов - мы не можем реально помочь. Может быть, вы просто пропустите какой-нибудь разумный индекс? Кто знает - вы ничего нам не говорите (нет вывода плана запроса, нет дефиниции таблиц, нет определений индексов).

Возможно, также не следует злоупотреблять типами данных: Объявить @Datum varchar - OUCH. Когда-либо слышал о типе данных DATE на сервере sql?

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