Milloin SELECT… INTO -käskyä (PE003) käytetään
Voimme käyttää SELECT…INTO
-palvelua SQL Serverissä uuden taulukon luomiseen taulukon lähteestä. SQL Server käyttää SELECT
-luettelon lausekkeiden määritteitä uuden taulukon rakenteen määrittämiseen.
Ennen SQL Server 2005: n käyttöä SELECT…INTO
tuotantokoodissa oli suorituskyvyn ”koodihaju”, koska se hankki skeeman lukot tietokannan järjestelmätaulukoihin, jolloin SQL Server ei näytä reagoivan kyselyn suorituksen aikana. Tämä johtuu siitä, että kyseessä on implisiittisen tapahtuman DDL-käsky, joka on väistämättä pitkäaikainen, koska tiedot lisätään samaan SQL-lauseeseen. Tämä ongelma korjautui kuitenkin SQL Server 2005: ssä, kun lukitusmalli muuttui.
SELECT…INTO
tuli suosittu, koska se oli nopeampi tapa lisätä tietoja kuin käyttää INSERT
INTO…SELECT…
. Tämä johtui pääasiassa siitä, että SELECT…INTO
-operaatio kirjataan mahdollisuuksien mukaan joukkolokiin. Vaikka INSERT
INTO
voidaan nyt kirjata joukkolokiin, saatat silti nähdä tämän suorituskykyedun SQL Server 2012: ssa ja 2014: ssä, koska SELECT…INTO
voidaan rinnastaa näihin versioihin, kun taas INSERT
INTO
-sivun rinnakkaisuuden tuki syntyi vain SQL Serverissä 2016. SELECT…INTO
-kohdassa sinulla on kuitenkin edelleen tehtävä määritellä kaikki vaaditut indeksit ja rajoitukset ja niin edelleen uudessa taulukossa.
Suositus vältä SELECT…INTO
: n käyttöä tuotantokoodille, sisältyy koodianalyysisääntöön SQL-kehotteessa (PE003).
Taulukoiden luominen SELECT INTO -käskyllä
SQL serverin SELECT…INTO
-ominaisuus on suunniteltu tallentamaan tai ’säilyttämään’ taulukon lähde osana prosessia. Tässä on yksinkertainen esimerkki:
Taulukon lähde voi kuitenkin olla monia muita asioita kuin tavanomainen taulukko, kuten käyttäjän määrittämä funktio, OpenQuery
, OpenDataSource
, OPENXML
-lauseke, johdettu taulukko, yhdistetty taulukko, käännetty taulukko, etätietolähde, taulukon muuttuja tai muuttujatoiminto. Näiden eksoottisempien taulukolähteiden kanssa SELECT…INTO
-syntaksista tulee hyötyä.
ON VALITTU ANSI-osaan standardi?
ANSI-standardit tukevat SELECT…INTO
-rakennetta; Sitä kutsutaan singleton selectiksi ja se lataa yhden rivin arvoilla, mutta sitä käytetään hyvin harvoin (Kiitos Joe Celkolle tämän osoittamisesta).
Ihmiset käyttävät usein SELECT…INTO
väärinymmärryksessä siitä, että se on nopea tapa kopioida taulukoita, joten on yllätys, että mikään indeksistä, rajoituksista, lasketuista sarakkeista tai laukaisimista lähdetaulukko siirretään uuteen taulukkoon. Niitä ei voida määrittää SELECT…INTO
-lausekkeessa. Se ei myöskään tee mitään mitätöimättä tai laskettujen sarakkeiden säilyttämisestä. Kaikki nämä tehtävät on tehtävä takautuvasti käytettävissä olevien tietojen kanssa, mikä vie väistämättä aikaa.
Voit kuitenkin käyttää toimintoa IDENTITY
(tietotyyppi, siemen, inkrementti) identiteettikentän asettamiseksi, ja kun lähde on yksi taulukko, on mahdollista tehdä kohdetaulukon sarake identiteettisarakkeeksi. Tämä tosiasia saa todennäköisesti kehittäjät olettamaan, että se siirtää muita sarakeominaisuuksia.
Lisäksi se ei myöskään voi luoda osioituja taulukoita, harvinaisia sarakkeita tai muita lähdetaulukosta perittyjä määritteitä. Kuinka se voisi tapahtua, kun tiedot saattavat olla peräisin kyselystä, johon liittyy useita liittymiä, tai jostakin eksoottisesta ulkoisesta tietolähteestä?
Koska SQL 2012 SP1 CU10, SELECT…INTO
voi Suorita samanaikaisesti, SQL Server 2016: n jälkeen Parallel Insert on kuitenkin sallittu tavanomaisessa INSERT INTO…SELECT
-lausekkeessa tietyin rajoituksin, joten SELECT
… INTO
on nyt melko vähentynyt. INSERT
INTO
-prosessia voidaan myös nopeuttaa, jos se voidaan kirjata joukkolokiin eikä palauttaa kokonaan asettamalla palautusmalli yksinkertaiseen tai joukkolokiin, lisäämällä tyhjään taulukkoon tai kasaan ja asettamalla taulukon TABLOCK
-vihje.
Seuraava tiivistää joitain rajoituksia ja rajoitukset käytettäessä SELECT…INTO
.
- Sarakkeen
IDENTITY
ominaisuus siirretään, mutta ei, jos:- Lauseke
SELECT
sisältää liitettyjä taulukoita (käyttäen jokoJOIN
taiUNION
),GROUP
BY
-lauseke tai aggregaattitoiminto.Jos sinun on vältettäväIDENTITY
-ominaisuuden siirtymistä uuteen taulukkoon, mutta tarvitset sarakkeen arvoja, kannattaa lisätäJOIN
taulukkolähteeseesi ehdolla, joka ei ole koskaan totta, taiUNION
, joka ei sisällä rivejä. -
IDENTITY
-sarake on lueteltu useammin kuin kerranSELECT
-luettelossa -
IDENTITY
-sarake on osa lausekkeen -
IDENTITY
-sarake on etätietolähteestä
- Lauseke
- Et voi
SELECT…INTO
joko taulukon arvoinen parametri tai taulukon muuttuja kohteeksi, vaikka voit valita neFROM
. - Vaikka lähde on osioitu taulukko, uusi taulukko luodaan oletustiedostoryhmään. SQL Server 2017: ssä on kuitenkin mahdollista määrittää
ON
-lausekkeen avulla tiedostoryhmä, johon kohdetaulukko luodaan. - Voit määrittää
ORDER
BY
-lauseke, mutta se jätetään yleensä huomiotta. Tämän vuoksiIDENTITY_INSERT
-järjestystä ei taata. - Kun laskettu sarake sisältyy
SELECT
luettelo, vastaava sarake uudessa taulukossa ei ole laskettu sarake. Uuden sarakkeen arvot ovat arvoja, jotka laskettiin silloin, kunSELECT…INTO
suoritettiin. - Kuten
CREATE
TABLE
-lauseke, jos lausekeSELECT…INTO
sisältää nimenomaisen tapahtuman, kyseisten järjestelmätaulukoiden alla olevat rivit ovat lukittu yksinomaan, kunnes kauppa on nimenomaisesti tehty. Tällä välin tämä johtaa lohkoihin muissa prosesseissa, jotka käyttävät näitä järjestelmätaulukoita.
On joitain sekaannuksia ongelmista, joita voi ilmetä käytettäessä SELECT…INTO
käyttämällä väliaikaisia taulukoita. SELECT…INTO
on saanut jonkin verran epäoikeudenmukaisen maineen tästä, mutta se oli osa yleisempää ongelmaa, joka koski salvan kiistelyä tempdb
raskaalla kuormalla pienen temp-taulukon luomisesta ja poistamisesta. Kun SELECT…INTO
hyväksyttiin innokkaasti, se voi lisätä huomattavasti tämän tyyppistä toimintaa. Ongelma voidaan helposti korjata SQL Server 2000: sta eteenpäin ottamalla käyttöön jäljityslippu TF1118, jota ei enää tarvita SQL Server 2016: sta eteenpäin. Täydellinen selitys on kohdassa TF 1118: n väärinkäsitykset.
Yhteenveto
Yhteenvetona SELECT…INTO
on hyvä tapa tehdä taulukko- lähde väliaikaisesti pysyvä osana prosessia, jos et välitä rajoituksista, hakemistoista tai erityisistä sarakkeista. Se ei ole hyvä tapa kopioida taulukkoa, koska vain taulukon kaavion tärkeimmät olennaiset osat voidaan kopioida. Vuosien mittaan on ollut tekijöitä, jotka ovat lisänneet tai vähentäneet SELECT…INTO
: n vetovoimaa, mutta kaiken kaikkiaan on hyvä välttää sen käyttöä aina, kun se on mahdollista. Luo sen sijaan taulukko nimenomaisesti kaikilla taulukon ominaisuuksilla, jotka on suunniteltu varmistamaan tietojen yhdenmukaisuus.