2012-03-29 10 views

Odpowiedz

2

Pod względem wydajności nie. To tylko mniej kodu do napisania i łatwiejszy do odczytania (moim zdaniem).

+1

W rzeczywistości może być znacząca korzyść z wydajności, jeśli duża liczba pojedynczych instrukcji INSERT zostanie wysłana przez połączenie sieciowe. Zobacz [moja odpowiedź tutaj] (http://stackoverflow.com/a/25879264/2144390) na przykład. –

1

Jeśli będzie wstawienie więcej niż jedną kolumnę danych z SELECT oprócz swoich jawnie wpisywanych wierszach tabeli wartości Konstruktor będzie wymagać, aby przeliterować każdą kolumnę indywidualnie, w przeciwieństwie do tego, kiedy używasz jednej INSERT oświadczenie, możesz określić wiele kolumn w SELECT.

Na przykład:

USE AdventureWorks2008R2; 
GO 
CREATE TABLE dbo.MyProducts (Name varchar(50), ListPrice money); 
GO 
-- This statement fails because the third values list contains multiple columns in the subquery. 
INSERT INTO dbo.MyProducts (Name, ListPrice) 
VALUES ('Helmet', 25.50), 
     ('Wheel', 30.00), 
     (SELECT Name, ListPrice FROM Production.Product WHERE ProductID = 720); 
GO 

zawiedzie; trzeba by zrobić to tak:

INSERT INTO dbo.MyProducts (Name, ListPrice) 
VALUES ('Helmet', 25.50), 
     ('Wheel', 30.00), 
     ((SELECT Name FROM Production.Product WHERE ProductID = 720), 
     (SELECT ListPrice FROM Production.Product WHERE ProductID = 720)); 
GO 

zobaczyć Table Value Constructor Limitations and Restrictions

-2

Nie ma żadnych korzyści wydajności jak wspomniano Abe.

Kolejność konstruktora kolumn jest żądaną wartością dla wartości (lub instrukcji select). Możesz wyświetlić kolumny w dowolnej kolejności - wartości będą musiały być zgodne z tą kolejnością.

Jeżeli przypadkowo przełączyć kolumny w instrukcji SELECT (lub wartości klauzuli) i typy danych są kompatybilne z wykorzystaniem kolumn skonstruować pomoże Ci znaleźć problem.

1

Odpowiedzi na to pytanie dotąd były bardzo mylący (i wykazują kompletny brak wysiłku/zrozumienia), a tam jest dość duża różnica wydajności pomiędzy:

declare @numbers table (n int not null primary key clustered); 

insert into @numbers (n) 
values (0) 
    , (1) 
    , (2) 
    , (3) 
    , (4); 

i

declare @numbers table (n int not null primary key clustered); 

insert into @numbers (n) values (0); 
insert into @numbers (n) values (1); 
insert into @numbers (n) values (2); 
insert into @numbers (n) values (3); 
insert into @numbers (n) values (4); 

Fakt, że każde oświadczenie insert ma swoją własną transakcję niejawną, gwarantuje to. Możesz to łatwo udowodnić, przeglądając plany wykonania dla każdej instrukcji lub wykonując czas wykonania egzaminu przy użyciu set statistics time on;. Istnieje stały koszt związany z "ustawieniem" i "zerwaniem" kontekstu dla każdego pojedynczego wkładu, a drugie zapytanie musi zapłacić tę karę pięć razy, podczas gdy pierwsza płaci tylko raz.

Nie tylko jest metoda lista bardziej wydajne, ale można też użyć go do budowy tabelę pochodzącą:

select * 
from (values 
    (0) 
    , (1) 
    , (2) 
    , (3) 
    , (4) 
) as Numbers (n); 

Format ten omija ograniczenia 1000 wartości i pozwala połączyć i filtrować listę przed nim jest wstawiony. Można również zauważyć, że w ogóle nie jesteśmy zobowiązani do oświadczenia insert! Jako de facto tabela, ta konstrukcja może być używana wszędzie tam, gdzie odniesienie do tabeli byłoby poprawne.

+1

Może również istnieć znacząca korzyść z wydajności, jeśli duża liczba pojedynczych instrukcji INSERT zostanie wysłana przez połączenie sieciowe. –

+0

@GordThompson Zdecydowanie. Jeśli wstawiasz 10 000 wierszy w sieci za pomocą pojedynczych instrukcji, to marnujesz co najmniej 240 000 bajtów wymaganych do wysłania ciągu znaków 'insert into 'over wire 10 000 razy. Każdy kolejny znak, który dodasz do nazwy tabeli/kolumny, to dwa dodatkowe bajty, które należy wysłać, odebrać i przeanalizować, zanim zacznie obowiązywać którykolwiek z elementów napisanych w moim poście powyżej ... – Kittoes0124

Powiązane problemy