Programmering

SQL frigjort: 17 måter å få fart på SQL-spørsmålene dine

SQL-utviklere på hver plattform sliter, tilsynelatende fast i en GJØR MENS løkke som får dem til å gjenta de samme feilene igjen og igjen. Det er fordi databasefeltet fremdeles er relativt umoden. Visst, leverandører gjør noen fremskritt, men de fortsetter å takle de større problemene. Samtidighet, ressursadministrasjon, plassadministrasjon og hastighet plager fortsatt SQL-utviklere, enten de koder på SQL Server, Oracle, DB2, Sybase, MySQL eller andre relasjonsplattformer.

En del av problemet er at det ikke er noen magisk kule, og for nesten alle beste praksis kan jeg vise deg minst ett unntak. Vanligvis finner en utvikler sine egne favorittmetoder - men vanligvis inneholder de ingen konstruksjoner for ytelse eller samtidighet - og gidder ikke å utforske andre alternativer. Kanskje det er et symptom på mangel på utdannelse, eller utviklerne er bare for nærme prosessen til å gjenkjenne når de gjør noe galt. Kanskje spørringen kjører bra på et lokalt sett med testdata, men mislykkes stort i produksjonssystemet.

Jeg forventer ikke at SQL-utviklere blir administratorer, men de må ta hensyn til produksjonsproblemer når de skriver koden. Hvis de ikke gjør det under den første utviklingen, vil DBA bare få dem til å gå tilbake og gjøre det senere - og brukerne lider i mellomtiden.

Det er en grunn til at vi sier at innstilling av en database er både en kunst og en vitenskap. Det er fordi det er veldig få harde og raske regler som gjelder over hele linja. Problemene du har løst på ett system er ikke problemer med et annet, og omvendt. Det er ikke noe riktig svar når det gjelder å stille inn spørsmål, men det betyr ikke at du skal gi opp.

Det er noen gode prinsipper du kan følge som skal gi resultater i en eller annen kombinasjon. Jeg har innkapslet dem i en liste over SQL-doser og don'ts som ofte blir oversett eller er vanskelig å få øye på. Disse teknikkene skal gi deg litt mer innsikt i hodet til DBA-ene dine, samt muligheten til å begynne å tenke prosesser på en produksjonsorientert måte.

1. Ikke bruk OPPDATER i stedet for SAK

Dette problemet er veldig vanlig, og selv om det ikke er vanskelig å oppdage, overser mange utviklere det ofte fordi de bruker OPPDATER har en naturlig ow som virker logisk.

Ta for eksempel dette scenariet: Du setter inn data i en temp-tabell og trenger det for å vise en viss verdi hvis en annen verdi eksisterer. Kanskje du henter fra kundetabellen, og du vil at alle med mer enn $ 100 000 i bestillinger skal bli merket som "Foretrukket." Dermed setter du inn dataene i tabellen og kjører en OPPDATER uttalelse for å sette CustomerRank-kolonnen til "Foretrukket" for alle som har mer enn $ 100.000 i bestillinger. Problemet er at OPPDATER uttalelse logges, noe som betyr at den må skrive to ganger for hver eneste skriving til tabellen. Veien rundt dette er selvfølgelig å bruke en innebygd SAK uttalelse i selve SQL-spørringen. Dette tester hver rad for bestillingsbeløpet og setter etiketten "Foretrukket" før den skrives til tabellen. Ytelsesøkningen kan være svimlende.

2. Ikke bruk kode blindt

Dette problemet er også veldig vanlig. Det er veldig enkelt å kopiere andres kode fordi du vet at den henter dataene du trenger. Problemet er at det ofte trekker mye mer data enn du trenger, og utviklere gidder sjelden å trimme det ned, så de ender med et enormt datasett. Dette kommer vanligvis i form av en ekstra ytre skjøt eller en ekstra tilstand i HVOR klausul. Du kan få enorme ytelsesgevinster hvis du trimmer gjenbrukt kode etter dine nøyaktige behov.

3. Dra bare det antall kolonnene du trenger

Dette problemet ligner på nummer 2, men det er spesifikt for kolonner. Det er altfor lett å kode alle spørsmålene dine med Å VELGE * i stedet for å liste opp kolonnene hver for seg. Problemet igjen er at det trekker mer data enn du trenger. Jeg har sett denne feilen flere titalls ganger. En utvikler gjør en Å VELGE * spørre mot et bord med 120 kolonner og millioner av rader, men bruker bare tre til fem av dem. På det tidspunktet behandler du så mye mer data enn du trenger, det er rart spørringen returnerer i det hele tatt. Du behandler ikke bare mer data enn du trenger, men du tar også ressurser fra andre prosesser.

4. Ikke dopp

Her er en annen jeg har sett flere ganger enn jeg burde ha: En lagret prosedyre er skrevet for å hente data fra en tabell med hundrevis av millioner av rader. Utvikleren trenger kunder som bor i California og har inntekter på mer enn $ 40.000. Så han spør etter kunder som bor i California og legger resultatene i en temp-tabell; så spør han etter kunder med inntekter over $ 40 000 og setter resultatene i en annen temp-tabell. Til slutt blir han med på begge bordene for å få sluttproduktet.

Tuller du med meg? Dette bør gjøres i en enkelt spørring; i stedet dobbeltdypper du et stort bord. Ikke vær en idiot: Spørre store bord bare én gang når det er mulig - du vil finne ut hvor mye bedre prosedyrene dine utfører.

Et litt annet scenario er når det er behov for en delmengde av en stor tabell av flere trinn i en prosess, noe som fører til at det store spørsmålet blir spurt hver gang. Unngå dette ved å spørre etter delsettet og vedvare det andre steder, og deretter peke de påfølgende trinnene på det mindre datasettet.

6. Gjør data på forhånd

Dette er et av favorittemnene mine fordi det er en gammel teknikk som ofte blir oversett. Hvis du har en rapport eller en prosedyre (eller enda bedre, et sett med dem) som vil gjøre lignende sammenføyninger til store tabeller, kan det være en fordel for deg å pre-scene dataene ved å bli med i tabellene på forhånd og vedvare dem inn i et bord. Nå kan rapportene løpe mot det forhåndsinnstilte bordet og unngå den store sammenføyningen.

Du er ikke alltid i stand til å bruke denne teknikken, men når du kan, vil du finne at det er en utmerket måte å spare serverressurser på.

Vær oppmerksom på at mange utviklere kommer rundt dette sammenføyningsproblemet ved å konsentrere seg om selve spørringen og lage en visning bare rundt sammenføyningen, slik at de ikke trenger å skrive sammenforholdsvilkårene igjen og igjen. Men problemet med denne tilnærmingen er at spørringen fortsatt kjører for hver rapport som trenger det. Ved å forhåndsstappe dataene, kjører du sammenføyningen bare en gang (si 10 minutter før rapportene), og alle andre unngår den store sammenføyningen. Jeg kan ikke fortelle deg hvor mye jeg elsker denne teknikken; i de fleste miljøer er det populære bord som blir sammen hele tiden, så det er ingen grunn til at de ikke kan forhåndsinnsettes.

7. Slett og oppdater i grupper

Her er en annen enkel teknikk som blir oversett mye. Sletting eller oppdatering av store mengder data fra store tabeller kan være et mareritt hvis du ikke gjør det riktig. Problemet er at begge disse uttalelsene kjører som en enkelt transaksjon, og hvis du trenger å drepe dem, eller hvis noe skjer med systemet mens de jobber, må systemet rulle tilbake hele transaksjonen. Dette kan ta veldig lang tid. Disse operasjonene kan også blokkere andre transaksjoner så lenge de varer, og i hovedsak flaskehalser systemet.

Løsningen er å gjøre slettinger eller oppdateringer i mindre batcher. Dette løser problemet ditt på noen måter. For det første, hvis transaksjonen blir drept av en eller annen grunn, har den bare et lite antall rader å rulle tilbake, så databasen returnerer mye raskere online. For det andre, mens de mindre gruppene forplikter seg til disken, kan andre snike seg inn og gjøre noe arbeid, slik at samtidigheten forbedres sterkt.

Langs disse linjene har mange utviklere det sittende fast i hodet at disse slettings- og oppdateringsoperasjonene må fullføres samme dag. Det er ikke alltid sant, spesielt hvis du arkiverer. Du kan strekke ut denne operasjonen så lenge du trenger, og de mindre gruppene hjelper til med å oppnå det. Hvis du kan ta lengre tid å utføre disse intensive operasjonene, bruk den ekstra tiden og ikke ta systemet ned.

8. Bruk midlertidige tabeller for å forbedre markørens ytelse

Jeg håper vi alle vet nå at det er best å holde seg borte fra markører hvis det er mulig. Markører lider ikke bare av hastighetsproblemer, som i seg selv kan være et problem med mange operasjoner, men de kan også føre til at operasjonen din blokkerer andre operasjoner mye lenger enn det er nødvendig. Dette reduserer samtidigheten i systemet ditt.

Du kan imidlertid ikke alltid unngå å bruke markører, og når disse tidene oppstår, kan du kanskje komme deg vekk fra markørinduserte ytelsesproblemer ved å gjøre markøroperasjonene mot en temp-tabell i stedet. Ta for eksempel en markør som går gjennom en tabell og oppdaterer et par kolonner basert på noen sammenligningsresultater. I stedet for å gjøre sammenligningen mot live tabellen, kan du kanskje sette dataene i en temp-tabell og gjøre sammenligningen mot det i stedet. Så har du en singel OPPDATER uttalelse mot livebordet som er mye mindre og holder låser bare i kort tid.

Hvis du klipper dataendringene dine som dette, kan det øke samtidigheten. Jeg avslutter med å si at du nesten aldri trenger å bruke en markør. Det er nesten alltid en settbasert løsning; du må lære å se det.

9. Ikke hekk utsikten

Visninger kan være praktiske, men du må være forsiktig når du bruker dem. Mens visninger kan bidra til å skjule store spørsmål fra brukere og til å standardisere datatilgang, kan du enkelt komme i en situasjon der du har visninger som kaller visninger som kaller visninger som kaller visninger. Dette kalles hekkende utsikt, og det kan forårsake alvorlige ytelsesproblemer, spesielt på to måter:

  • For det første vil du sannsynligvis ha mye mer data som kommer tilbake enn du trenger.
  • For det andre vil spørreoptimalisereren gi opp og returnere en dårlig spørringsplan.

Jeg hadde en gang en klient som elsket hekkende utsikt. Klienten hadde en visning den brukte for nesten alt fordi den hadde to viktige sammenføyninger. Problemet var at utsikten returnerte en kolonne med 2 MB dokumenter i. Noen av dokumentene var enda større. Klienten presset minst 2 MB ekstra over nettverket for hver rad i nesten hver eneste spørring den kjørte. Naturligvis var spørringsytelsen avskyelig.

Og ingen av spørsmålene brukte faktisk den kolonnen! Selvfølgelig ble kolonnen begravet syv visninger dypt, så selv å finne det var vanskelig. Da jeg fjernet dokumentkolonnen fra visningen, gikk tiden for den største forespørselen fra 2,5 timer til 10 minutter. Da jeg endelig avslørte de nestede visningene, som hadde flere unødvendige sammenføyninger og kolonner, og skrev et vanlig spørsmål, falt tiden for den samme spørringen til undersekunder.

$config[zx-auto] not found$config[zx-overlay] not found