sql >> Database >  >> RDS >> Sqlserver

Prestaties van verschillende benaderingen van op tijd gebaseerde gegevens

Aan de ene kant is het goed dat je een nieuwe vraag hebt geopend. Maar aan de andere kant, door één vraag te extraheren en te vragen of deze sneller werkt, de context van de vorige vraag verliest, is de nieuwe vraag te geïsoleerd. Zoals u ongetwijfeld weet, maken het beheren van een database, het beheren van bronnen (geheugen/cache, schijf, CPU-cycli), het beheren van code (goed of slecht) die gebruikmaakt van die bronnen, allemaal deel uit van het hele plaatje. Performance is een ruilspel, niets is gratis.

  1. Het belangrijkste probleem dat ik had, was de duplicatie van de EndDate-kolom, die gemakkelijk kan worden afgeleid. Dubbele kolommen zijn gelijk aan Update anomalieën. Smirkingman heeft het klassieke voorbeeld gegeven:sommige zoekopdrachten krijgen het ene resultaat en andere vragen het andere. Dat kan gewoon niet bij grote organisaties; of in banken (althans in ontwikkelde landen) waar de gegevens worden gecontroleerd en beschermd. Je hebt een basisregel voor normalisatie overtreden en er moeten boetes worden betaald.

    • Anomails bijwerken; twee versies (reeds gedetailleerd). Auditors mogen het systeem niet passeren.

    • Tabelgrootte
      In elke grote tabel is het een probleem, en vooral in tijdreeksen of temporele gegevens, waar het aantal kolommen klein is en het aantal rijen enorm. Dus wat, sommigen zullen zeggen, schijfruimte is goedkoop. Ja, dat geldt ook voor soa's. Waar het om gaat is waarvoor het wordt gebruikt en hoe goed men er voor zorgt.

      • Schijfruimte
        Misschien goedkoop op een pc, maar op een productieserver niet. In principe heb je 62% opgeteld bij de rijgrootte (13 plus 8 is gelijk aan 21) en dus de tabelgrootte. Bij de bank die ik momenteel toegewezen heb, wordt elke afdeling die eigenaar is van de gegevens als volgt in rekening gebracht, SAN-gebaseerde opslag is alles wat er is. Cijfers zijn per GB per maand (dit is geen high-end Australische bank):

        $ 1,05 voor RAID5 Unmirrored
        (we weten dat het traag is, maar het is goedkoop, zet er gewoon geen belangrijke informatie op, want als het kapot gaat, nadat de nieuwe schijf heet of koud is verwisseld, duurt het dagen voordat om zichzelf opnieuw te synchroniseren.)

        $2,10 voor RAID5 Mirrored
        In het SAN tenminste.

        $ 4,40 voor RAID1+0
        Minimum voor productiegegevens, back-up van transactielogboeken en nachtelijke databasedumps.

        $9,80 voor RAID1+0 Gerepliceerd
        Naar een identieke SAN-layout op een andere, bomvrije site. Productiestop in minuten; bijna nul transactieverlies.

      • Geheugen/Cache
        Ok, Oracle heeft het niet, maar de serieuze bankdatabases hebben wel caches en ze worden beheerd. Gezien een specifieke cachegrootte, past slechts 62% van de rijen in dezelfde cachegrootte.

      • Logische &Fysieke I/O
        Dat betekent 50% meer I/O om de tabel te lezen; zowel streamen naar cache als schijflezen.

  2. Daarom is het een academische kwestie of de query afzonderlijk beter of slechter presteert. In de context van het bovenstaande is de tabel is traag en presteert altijd 62% slechter bij elke toegang. En het beïnvloedt elke andere gebruiker op de server. De meeste DBA's zullen het niet schelen (dat zou ik zeker niet doen) als het subqueryformulier met de helft van de snelheid presteert, omdat hun bonus gekoppeld is aan auditacceptatie, niet alleen aan codeprestaties.

    • Bovendien is er het extra voordeel dat u nooit de code opnieuw hoeft te bezoeken en transacties hoeft te corrigeren vanwege Update-anomalieën.

    • En de transacties hebben minder punten om bij te werken, dus ze zijn kleiner; minder blokkerende sloten, enz.

  3. Akkoord, die discussie in de opmerkingen is moeilijk. In mijn antwoord heb ik twee subquery's gedetailleerd en uitgelegd. Er was een misverstand:u had het over deze subquery (in de WHERE-clausule, een tabelsubquery ) en ik had het over de andere subquery (in de kolomlijst, een scalaire subquery ) toen ik zei dat het zo snel of sneller presteert. Nu dat is opgehelderd, kan ik niet zeggen dat de eerste query hierboven (subquery in de WHERE-component, een tabel) net zo snel zal presteren als de tweede query (met de gedupliceerde kolom); de eerste moet 3 scans uitvoeren, terwijl de tweede slechts 2 scans uitvoert. (Ik durf wel te zeggen dat de tweede een scan zal maken.)

    Het punt is, naast het isolatieprobleem, het is geen eerlijke vergelijking, ik maakte de opmerking over scalaire subquery's. Ik zou niet willen suggereren dat een 3-scan-query even snel of sneller is dan een 2-scan-query.

    De uitspraak die ik heb gedaan over de subquery van de 3-scantabel (die ik hier citeer) moet in de volledige context worden genomen (ofwel dat bericht in zijn geheel, ofwel het bovenstaande). Ik deins er niet voor terug.

    Ik besteed de helft van mijn leven aan het verwijderen van illegale alternatieven zoals dubbele kolommen, die gebaseerd zijn op de kwestie van prestaties, waarbij de makers de mantra scanderen dat de tafel traag is, dus hebben ze "gedenormaliseerd voor prestaties". Het resultaat, voorspelbaar voordat ik begin, is een tafel half zo groot, die tweemaal zo snel presteert algemeen . De Times Series is de meest voorkomende vraag hier (de link linkt naar een andere vraag; die linkt naar een andere), maar stel je het probleem voor in een bankdatabase:dagelijkse OpeningExposure en ClosingExposure per Security per Holding perUnitTrust perPortfolio .

  4. Maar laat me een vraag beantwoorden die niet is gesteld. Dit soort interactie is normaal, niet ongebruikelijk bij het werken met interne ontwikkelingsteams; het komt minstens één keer per maand op. Een crash-hot ontwikkelaar heeft zijn code al geschreven en getest, met behulp van een tabel met een gedupliceerde kolom, het vliegt, en nu is het vastgelopen omdat ik het niet in de db zal plaatsen.

    Nee, ik zal het testen binnen de context van het hele systeem en:

    • de helft van de tijd gaat de tabel binnen zonder de kolom EndDate, omdat er geen probleem is dat een query van een halve seconde nu in één seconde wordt uitgevoerd.

    • De andere helft van de tijd zijn de prestaties van [table subquery] niet acceptabel, dus implementeer ik een boolean (bit) indicator om IsCurrent te identificeren . Dat is veel beter dan een dubbele kolom en biedt 2-scansnelheden.

    • In geen miljoen jaar krijg je me zover dat ik een column dupliceer; 62% toevoegen aan de tafelgrootte; de tafel vertragen in de volledige multi-user context met 62%; en het risico lopen een audit te laten mislukken. En ik ben geen werknemer, ik krijg geen bonus.

    Dat zou het testen waard zijn:zoekopdracht met een dubbele kolom versus zoekopdracht met een IsCurrent indicator, in de volledige context van het algemene gebruik van hulpbronnen.

  5. Smirkingman heeft een goed punt naar voren gebracht. En ik zal het duidelijk herhalen, zodat het niet gefragmenteerd raakt en dan wordt het ene of het andere fragment aangevallen. Verbreek dit alsjeblieft niet:

    Een relationele database,
    Genormaliseerd door een ervaren relationele modelleur, tot echte vijfde normaalvorm

    (geen updateafwijkingen; geen dubbele kolommen),
    met volledige relationele naleving
    (IDEF1X, in het bijzonder met betrekking tot het minimaliseren van Id Primaire sleutels; en dus de kracht van de relationele motor niet verlammend)
    zal resulteren in meer, kleinere tabellen, een kleinere database,
    met minder indexen,
    waardoor minder joins nodig zijn

    (dat klopt, meer tafels maar minder joins),
    en het presteert beter dan alles wat een van deze regels overtreedt
    op dezelfde hardware en onderneming db-platform

    (exclusief freeware, MS, Oracle; maar laat dat je niet tegenhouden),
    in de volledige context van productie-OLTP-gebruik
    met ten minste één orde van grootte,
    en het zal veel gemakkelijker te gebruiken zijn
    en te veranderen

    (nooit "refactoring" nodig).

    Ik heb dit minstens 80 keer gedaan. Twee ordes van grootte zijn niet ongebruikelijk, als ik het zelf doe, in plaats van iemand anders het kader te geven om het te doen.

Noch ik, noch de mensen met wie ik werk of die mij betalen, maakt het niet uit wat één vraag afzonderlijk zal doen.



  1. Oracle SQL zet waarden van een kolom in één rij

  2. Automatische verhoging toevoegen aan bestaande kolom zonder de huidige recordwaarden te beïnvloeden

  3. JSON importeren in Mysql

  4. langzame mysql-query die honderdduizenden keren per uur moet worden uitgevoerd