Creative Saplings

När ska vi använda SELECT… INTO-satsen (PE003)

oktober 13, 2020
No Comments

Vi kan använda SELECT…INTO i SQL Server för att skapa en ny tabell från en tabellkälla. SQL Server använder attributen för uttrycken i SELECT -listan för att definiera strukturen för den nya tabellen.

Innan SQL Server 2005 används SELECT…INTO i produktionskoden var en prestanda ’kodlukt’ eftersom den förvärvade schemalås på systemtabeller i databasen, vilket fick SQL Server att inte svara när frågan kördes. Detta beror på att det är ett DDL-uttalande i en implicit transaktion, som oundvikligen är långvarig eftersom data infogas i samma SQL-uttalande. Detta beteende fixades dock i SQL Server 2005 när låsmodellen ändrades.

SELECT…INTO blev populär eftersom det var ett snabbare sätt att infoga data än att använda INSERT INTO…SELECT…. Detta berodde främst på att SELECT…INTO -operationen, om möjligt, var massloggad. Även om INSERT INTO nu kan massloggas kan du fortfarande se denna prestandafördel i SQL Server 2012 och 2014, eftersom SELECT…INTO kan parallelliseras i dessa versioner, medan stöd för parallellisering av INSERT INTO bara uppstod i SQL Server 2016. Men med SELECT…INTO har du fortfarande uppgiften att definiera alla nödvändiga index och begränsningar och så vidare i den nya tabellen.

En rekommendation till undvik användning av SELECT…INTO, för produktionskod, ingår som en kodanalysregel i SQL Prompt (PE003).

Skapa tabeller med SELECT INTO-satsen

Funktionen SELECT…INTO i SQL Server utformades för att lagra eller ’bestå’ en tabellkälla som en del av en process. Här är ett enkelt exempel:

En tabellkälla kan dock vara många andra saker än en konventionell tabell, till exempel en användardefinierad funktion, en OpenQuery, en OpenDataSource, en OPENXML -sats, en härledd tabell, en sammanfogad tabell, en svängbar tabell, en fjärrdatakälla, en tabellvariabel eller en variabel funktion. Det är med dessa mer exotiska tabellkällor som SELECT…INTO syntaxen blir mer användbar.

Är VÄLJ I EN del av ANSI standard?

ANSI-standarderna stöder en SELECT…INTO -konstruktion; den kallas en singleton select och den laddar en rad med värden, men den används mycket sällan (tack till Joe Celko för att han påpekade detta).

Människor använder ofta SELECT…INTO med missförståndet att det är ett snabbt sätt att kopiera tabeller, och det är därför en överraskning att inget av index, begränsningar, beräknade kolumner eller triggers definierade i källtabellen överförs till den nya tabellen. De kan inte anges i uttalandet SELECT…INTO. Det gör inte heller något om ogiltighet eller att bevara beräknade kolumner. Alla dessa uppgifter måste göras i efterhand med data på plats, vilket oundvikligen tar tid.

Du kan dock använda funktionen IDENTITY (datatyp, utsäde, inkrement) för att ställa in ett identitetsfält, och det är möjligt, när källan är en enda tabell, att göra en kolumn i måltabellen till en identitetskolumn. Det är detta som förmodligen får utvecklare att anta att det kommer att överföra andra kolumnattribut.

Dessutom kan det inte heller skapa partitionerade tabeller, glesa kolumner eller något annat attribut som ärvs från en källtabell. Hur kan det vara när data kan komma från en fråga som involverar många kopplingar eller från någon exotisk extern datakälla?

Sedan SQL 2012 SP1 CU10 kan SELECT…INTO köras parallellt, men sedan SQL Server 2016 har Parallel Insert tillåtits på det konventionella INSERT INTO…SELECT -utdraget, med vissa begränsningar, så alla prestandafördelar med att använda SELECT… INTO är nu ganska minskat. INSERT INTO -processen kan också påskyndas om den kan massloggas snarare än helt återställas genom att ställa in återställningsmodellen för enkel eller bulkloggad, infoga i en tom tabell eller en hög och ställa in TABLOCK tips för tabellen.

Följande sammanfattar några av begränsningarna och begränsningar när du använder SELECT…INTO.

  • IDENTITY -egenskapen för en kolumn överförs, men inte om:
    • Uttrycket SELECT innehåller sammanfogade tabeller (använder antingen JOIN eller UNION), GROUP BY sats eller samlad funktion.Om du behöver undvika att en IDENTITY -egenskap överförs till den nya tabellen, men behöver kolumnens värden, är det värt att lägga till en JOIN till din tabellkälla på ett villkor som aldrig är sant, eller en UNION som inte ger några rader.
    • IDENTITY -kolumnen listas mer än en gång i SELECT -listan
    • IDENTITY -kolumnen är en del för ett uttryck
    • Kolumnen IDENTITY kommer från en fjärrdatakälla
  • Du kan inte SELECT…INTO antingen en tabellvärderad parameter eller en tabellvariabel som destination, men du kan välja FROM dem.
  • Även om din källa är en partitionerad tabell, den nya tabellen skapas i standardfilgruppen. I SQL Server 2017 är det dock möjligt att ange den filgrupp där måltabellen skapas, via ON -satsen.
  • Du kan ange en ORDER BY klausul, men den ignoreras vanligtvis. På grund av detta garanteras inte ordningen på IDENTITY_INSERT.
  • När en beräknad kolumn ingår i SELECT listan, motsvarande kolumn i den nya tabellen är inte en beräknad kolumn. Värdena i den nya kolumnen är de värden som beräknades vid tiden SELECT…INTO kördes.
  • Som med en CREATE TABLE uttalande, om ett SELECT…INTO uttalande ingår i en uttrycklig transaktion, är de underliggande raderna i de berörda systemtabellerna uteslutande låst tills transaktionen uttryckligen har begåtts. Under tiden kommer detta att resultera i blockering av andra processer som använder dessa systemtabeller.

Det finns viss förvirring om problem som kan hända med användningen av SELECT…INTO med hjälp av tillfälliga tabeller. SELECT…INTO har fått ett något orättvist rykte för detta, men det var en del av ett mer generellt problem med spärrstrid i tempdb under tung belastning av små temp tabell skapande och radering. När SELECT…INTO antogs med entusiasm skulle det kunna öka denna typ av aktivitet kraftigt. Problemet kan enkelt lösas i SQL Server 2000 och framåt med introduktionen av spårningsflaggan TF1118, vilket inte längre krävs från SQL Server 2016 och framåt. För en fullständig förklaring, se Missuppfattningar kring TF 1118.

Sammanfattning

Sammanfattningsvis är SELECT…INTO ett bra sätt att skapa en tabell- källa tillfälligt ihållande som en del av en process, om du inte bryr dig om begränsningar, index eller speciella kolumner. Det är inte ett bra sätt att kopiera en tabell eftersom endast de viktigaste sakerna i tabellschemat kan kopieras. Under åren har det funnits faktorer som har ökat eller minskat attraktionen för SELECT…INTO, men totalt sett är det en bra idé att undvika att använda det när det är möjligt. Skapa istället en tabell uttryckligen, med hela utbudet av funktioner som tabellen har som är utformade för att säkerställa att data är konsekventa.

Articles
Previous Post

Bäggerceller: definition, funktioner, slemutsöndring och associerade sjukdomar

Next Post

Hälsosam mandelmjöl Pizza Crust Mix och degrecept (Paleo, glutenfri)

Lämna ett svar Avbryt svar

Senaste inläggen

  • Världens bästa fotoskolor, 2020
  • Suveräna medborgare tar sin regeringsfilosofi mot vägarna
  • Guide för reparation av stuckaturer
  • Muckrakers (Svenska)
  • Precision Oncology (Svenska)

Arkiv

  • februari 2021
  • januari 2021
  • december 2020
  • november 2020
  • oktober 2020
  • september 2020
  • Deutsch
  • Nederlands
  • Svenska
  • Norsk
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語
  • 한국어
Proudly powered by WordPress | Theme: Fmi by Forrss.