Sql Server занимает слишком много времени для загрузки - PullRequest
0 голосов
/ 07 июня 2019

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

SELECT DISTINCT  CONCAT(date,' ',FORMAT(CAST([dbo].[TALAGA_PL70_FEEDER_1].time as datetime) , 'HH')) as Time, 
              [dbo].[TALAGA_PL70_FEEDER_1].Ia, 
              [dbo].[TALAGA_PL70_FEEDER_1].Ib, 
              [dbo].[TALAGA_PL70_FEEDER_1].Ic, 
              [dbo].[TALAGA_PL70_FEEDER_1].Ineutral
          FROM [dbo].[TALAGA_PL70_FEEDER_1] 
          JOIN (
               SELECT CONCAT(date,' ',MIN(time)) as mints FROM [TALAGA_PL70_FEEDER_1]  
                WHERE (date >= '2019-04-26' 
                AND date  <= '2019-05-25')  
                GROUP BY date, DATEPART(hh, time)

            )tt 
          ON [dbo].[TALAGA_PL70_FEEDER_1].time = tt.mints AND [TALAGA_PL70_FEEDER_1].date = tt.mints
          ORDER BY 1 ASC

Вот пример результата sql:

Time          | Ia               | Ib                | Ic               |  Ineutral
-------------------------------------------------------------------------------------------
2019-04-26 00 | 169.809661865234 |  163.836029052734 | 157.159591674805 |  13.2650079727173
2019-04-26 01 | 159.619323730469 |  155.754028320313 | 149.516830444336 |  10.7174234390259
2019-04-26 02 | 152.855056762695 |  148.814056396484 | 140.819900512695 |  12.0351390838623
2019-04-26 03 | 146.969253540039 |  144.773056030273 | 135.900436401367 |  11.1566619873047

Схема таблицы:

GO
 CREATE TABLE [dbo].[TALAGA_PL70_FEEDER_1](
[id] [int] IDENTITY(1,1) NOT NULL,
[date] [date] NOT NULL,
[time] [time](7) NOT NULL,
[Ineutral] [float] NULL,
[Ia] [float] NULL,
[Ib] [float] NULL,
[Ic] [float] NULL,
[Iave] [float] NULL,
[Ig] [float] NULL
 ) ON [PRIMARY]

 GO
 ALTER TABLE [dbo].[TALAGA_PL70_FEEDER_1] ADD  CONSTRAINT 
 [DF__TALAGA_FEE__date__0F975522]  DEFAULT (getdate()) FOR [date]
 GO
 ALTER TABLE [dbo].[TALAGA_PL70_FEEDER_1] ADD  CONSTRAINT 
 [DF__TALAGA_FEE__time__108B795B]  DEFAULT (getdate()) FOR [time]

Ошибка, которую я получаю в своих веб-отчетах:

Array ([0] => Array ([0] => 08S01)[SQLSTATE] => 08S01 [1] => 258 [code] => 258 [2] => [Microsoft] [Драйвер ODBC 11 для SQL Server] Поставщик общей памяти: ошибка тайм-аута [258]. [Сообщение] => [Microsoft] [Драйвер ODBC 11 для SQL Server] Поставщик разделяемой памяти: ошибка тайм-аута [258].) [1] => Массив ([0] => 08S01 [SQLSTATE] => 08S01 [1] => 258 [код] => 258 [2] => [Microsoft] [Драйвер ODBC 11 для SQL Server] Ошибка канала связи [message] => [Microsoft] [Драйвер ODBC 11 для SQL Server] Ошибка канала связи) [2] => Массив ([0] => 08S01 [SQLSTATE] => 08S01 [1] => -2147467259 [code] => -2147467259 [2] => [Microsoft] [Драйвер ODBC 11 для SQL Server] Ошибка канала связи [сообщение] => [Microsoft] [Драйвер ODBC 11 для SQL Server] Канал связипровал))

Ответы [ 2 ]

1 голос
/ 07 июня 2019

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

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

Вам может также необходимо добавить условие where во внешний запрос для фильтрации в том же диапазоне дат, что и внутренний запрос.

0 голосов
/ 07 июня 2019

Попробуйте использовать оконные функции:

SELECT date,
       RIGHT('00' + DATENAME(hour, f.time), 2) as Time,
       f.Ia, f.Ib, f.Ic, f.Ineutral
FROM (SELECT f.*,
             ROW_NUMBER() OVER (PARTITION BY date, DATEPART(HOUR, f.time) ORDER BY f.time ASC) as seqnum
      FROM [dbo].[TALAGA_PL70_FEEDER_1] f
      WHERE date >= '2019-04-26' AND
            date <= '2019-05-25' 
     ) f
WHERE seqnum = 1;
ORDER BY 1 ASC;

Примечания:

  • Я обычно ненавижу смешивать типы, поэтому я разделил дату и час на отдельные столбцы.
  • FORMAT(), по слухам, намного медленнее, чем другие функции даты / времени, но я сомневаюсь, что это сильно повлияет на ваше время.
  • Для повышения производительности создайте индекс для date.
  • Вы ничего не можете сделать с ROW_NUMBER(), если не хотите добавить вычисляемый столбец.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...