2016-11-07 22 views
7

Mam Table Valued Constructor przez który wybieram około 1 million rekordów. Będzie on używany do innej tabeli.Tabela Wyceniony konstruktor Maksymalny limit wierszy w Wybierz

SELECT * 
FROM (VALUES (100,200,300), 
       (100,200,300), 
       (100,200,300), 
       (100,200,300), 
       ..... 
       ..... --1 million records 
       (100,200,300)) tc (proj_d, period_sid, val) 

Oto mój oryginalny zapytania: https://www.dropbox.com/s/ezomt80hsh36gws/TVC.txt?dl=0#

Kiedy zrobić powyższy select to jest po prostu pokazując Query wypełniony z błędami z pokazując żadnego komunikatu o błędzie.

enter image description here

Aktualizacja: Próbował złapać komunikat o błędzie lub numer błędu używając TRY/CATCH blok, ale nie ma sensu nadal ten sam błąd jak poprzedniego obrazu

BEGIN try 
    SELECT * 
    FROM (VALUES (100,200,300), 
        (100,200,300), 
        (100,200,300), 
        (100,200,300), 
        ..... 
        ..... --1 million records 
        (100,200,300)) tc (proj_d, period_sid, val) 
END try 

BEGIN catch 
    SELECT Error_number(), 
      Error_message() 
END catch 

Dlaczego to nie jest wykonywany jest jakaś granica dla konstruktora Table Valed w Select. Wiem, że dla Insert jest to 1000, ale wybieram tutaj.

+2

Sprawdź ten link: http://stackoverflow.com/questions/14790548/updating-4-million-records-in-sql-server-using-list-of-record-ids-as-input – Laxmi

+0

Wszystkie wartości literalne należy wkompilować w plan wykonania. Ile czasu zajmuje kompilacja zanim pojawi się błąd? –

+0

@MartinSmith - Mniej niż 5 sekund zawsze –

Odpowiedz

3

Nie ma znaczenia ciężko kodowane granica (65536 * Network Packet Rozmiar 4KB jest 268 MB a długość skrypt jest dalekie od tego), choć nie zaleca się stosowania tej metody dla dużej ilości wierszy.

Wyświetlany błąd jest zgłaszany przez narzędzia klienta, a nie SQL Server. Jeśli zbudować ciąg SQL w dynamicznym SQL kompilacji jest w stanie przynajmniej zacząć skutecznie

DECLARE @SQL NVARCHAR(MAX) = '(100,200,300), 
'; 

SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL, 1000000) + ' 
(100,200,300)) tc (proj_d, period_sid, val)'; 

SELECT @SQL AS [processing-instruction(x)] 
FOR XML PATH('') 

SELECT DATALENGTH(@SQL)/1048576.0 AS [Length in MB] --30.517705917 

EXEC(@SQL); 

Choć Zabiłem wyżej po ~ 30 minut czasu kompilacji i nadal nie przyniosły wiersz. Dosłowne wartości muszą być przechowywane wewnątrz samego planu jako tabela stałych, a SQL Server wydaje a lot of time próbując wyprowadzić o nich również właściwości.

SSMS jest aplikacją 32-bitową i rzuca std::bad_alloc wyjątek podczas analizowania partii

enter image description here

Próbuje wcisnąć element na wektorze znak, że osiągnął zdolność i jego próba zmiany rozmiaru nie z powodu do niedostępności wystarczająco dużego, ciągłego obszaru pamięci. Tak więc oświadczenie nigdy nie prowadzi nawet do serwera.

Pojemność wektorowa rośnie o 50% za każdym razem (tj. Po the sequence here). Zdolność do wzrostu wektora zależy od sposobu ułożenia kodu.

następujące potrzeby wzrastać z pojemności od 19 do 28

SELECT * FROM 
(VALUES 
(100,200,300), 
(100,200,300), 
(100,200,300), 
(100,200,300), 
(100,200,300), 
(100,200,300)) tc (proj_d, period_sid, val) 

i dodaje wymaga jedynie rozmiar 2

SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val) 

Poniżej wymaga zdolności> 63 i < = 94.

SELECT * 
FROM (VALUES 
     (100, 
     200, 
     300), 
     (100, 
     200, 
     300), 
     (100, 
     200, 
     300), 
     (100, 
     200, 
     300), 
     (100, 
     200, 
     300), 
     (100, 
     200, 
     300) 
     ) tc (proj_d, period_sid, val) 

Dla miliona rzędów jak w przypadku 1 pojemność wektora musi wzrosnąć do 3.543,306.

Może się zdarzyć, że jedna z poniższych czynności umożliwi parsowanie strony po stronie klienta.

  1. Zmniejsz liczbę podziałów linii.
  2. Restart SSMS w nadziei, że żądanie dużej ciągłej pamięci powiedzie się, gdy jest mniej fragmentacji przestrzeni adresowej.

Jednak nawet jeśli z sukcesem wyślesz go na serwer, to ostatecznie zabije serwer podczas generowania planu wykonawczego, tak jak to omówiono powyżej.

Będziesz znacznie lepiej korzystał z kreatora importu eksportu, aby załadować tabelę. Jeśli musisz to zrobić w TSQL, znajdziesz rozbicie go na mniejsze partie i/lub użycie innej metody, takiej jak shredowanie XML będzie działać lepiej niż Table Valued Constructors. Poniższe czynności wykonuję na przykład w ciągu 13 sekund na moim komputerze (chociaż jeśli korzystasz z SSMS, prawdopodobnie będziesz musiał rozpaść się na kilka partii zamiast wklejać ogromny łańcuch literowy XML).

DECLARE @S NVARCHAR(MAX) = '<x proj_d="100" period_sid="200" val="300" /> 
' ; 

DECLARE @Xml XML = REPLICATE(@S,1000000); 

SELECT 
    x.value('@proj_d','int'), 
    x.value('@period_sid','int'), 
    x.value('@val','int') 
FROM @Xml.nodes('/x') c(x) 
Powiązane problemy