При повороте 13 миллионов записей база данных tempDB заполняется в SQL Server, а поворот занимает более 28 часов - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть одна таблица, которая потребляет 13 миллионов записей (в будущем данные увеличатся), что составляет около 2,5 ГБ. Кроме того, эта таблица не является временной таблицей.Когда мы пытаемся повернуть таблицу SQL, вы получите результат, как показано ниже:

Сообщение 1105, Уровень 17, Состояние 2, Строка 56
Не удалось выделить место для объекта 'dbo.WORKFILE GROUP большая записьпереполнение хранилища: 140761897762816 'в базе данных' tempdb ', поскольку файловая группа' PRIMARY 'заполнена.Создайте место на диске, удалив ненужные файлы, удалив объекты в файловой группе, добавив дополнительные файлы в файловую группу или установив автоматический рост для существующих файлов в файловой группе

Кроме того, для поворота требуется слишком много времени.(более 28 часов) на этом сервере SQL больше не выполняется никакая другая задача.

у нас есть общая физическая память 16 ГБ на машине из 16 ГБ, 12 ГБ выделено для сервера SQL.эта машина имеет 4 ядра.Всего имеется 4 группы файлов для типа файлов ROWS Data и одна для LOG, в которой все 5 файлов расположены на отдельном диске, общий размер этого диска составляет 50 ГБ.начальный размер tempdb составляет 14 ГБ.Автоматический рост для всех файлов данных составляет 100 МБ, а максимальный размер не ограничен.

SQL-запрос, как показано ниже:

SET nocount ON 

SELECT * 
INTO isheetnewdata1_4_27 
FROM 
    (SELECT 
         historyid, 
         requestentityid, 
         fieldname, 
         fieldvalue, 
         siteid, 
         isheetid 
     FROM   
         synk_isheet_1_int  
     WHERE  
         historyid = 6 
         AND group1id = 27 
         AND group2id = 4) AS A 
PIVOT 
    (MAX(fieldvalue) 
     FOR fieldname IN ([ID], [LastName], [FirstName], [Age], [externalId])
    ) AS pvt 
ORDER BY 
    historyid, requestentityid

Table structure of synk_isheet_1_int

Обратите внимание, что имя поля может быть больше, чем у насдля поворота.

Я использую SQL Server 2016 в Microsoft Azure.Моя главная проблема в том, что поворот занимает более 28 часов, и из-за того, что размер базы данных tempdb достигает максимального размера этого диска.

Я понятия не имею, что делать на этом этапе.мне нужно увеличить размер диска, на котором находится файл базы данных tempdb?и увеличить физическую память этой машины и предоставить больше памяти для SQL Server?

Query execution plan

Expected pivot look like

Спасибо всем

1 Ответ

0 голосов
/ 07 декабря 2018

Прежде всего: пожалуйста, не размещайте фотографии данных.Никто не хочет вводить это. Лучше попытайтесь предоставить автономный образец для воспроизведения вашей проблемы.

Во-вторых: даже если эта таблица создана временно: с такими дорогими запросами это стоитдля создания индексов.

Вместо использования PIVOT вы можете использовать условное агрегирование .Идея состоит в том, чтобы использовать набор группировки, который уменьшает ваш целевой набор до одна строка на объект (что бы это ни было) и использовать CASE WHEN вместе с MAX() для установки Сводные столбцы .

SELECT t.historyid
      ,t.requestentityid
      ,MAX(CASE WHEN fieldname='ID' THEN fieldvalue END) AS ID
      ,MAX(CASE WHEN fieldname='LastName' THEN fieldvalue END) AS LastName
      ,MAX(CASE WHEN fieldname='Age' THEN fieldvalue END) AS Age
      ,MAX(CASE WHEN fieldname='externalId' THEN fieldvalue END) AS externalId
FROM synk_isheet_1_int t
WHERE t.historyid = 6 
  AND t.group1id = 27 
  AND t.group2id = 4
GROUP BY t.historyid,t.requestentityid;

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

Сокращенный пример

Это 1) показать принципы и 2) показать, как вы можете настроитьавтономный образец.

DECLARE @tbl TABLE(id INT,fieldname varchar(max),fieldvalue varchar(max));
insert into @tbl VALUES(1,'lastname','hugo')
                      ,(2,'age','23')
                      ,(1,'ID','12')
                      ,(2,'LastName','test');

SELECT t.id
      ,MAX(CASE WHEN t.fieldname='ID' THEN t.fieldvalue END) AS ID
      ,MAX(CASE WHEN t.fieldname='LastName' THEN t.fieldvalue END) AS LastName
      ,MAX(CASE WHEN t.fieldname='Age' THEN t.fieldvalue END) AS Age
      ,MAX(CASE WHEN t.fieldname='externalId' THEN t.fieldvalue END) AS externalId
FROM @tbl t
GROUP BY t.id
...