Vrijwel allemaal functies per rij hebben een impact op de prestaties, de enige echte vraag is:"Is de impact klein genoeg om je geen zorgen over te maken?".
Dit is iets dat je moet ontdekken door te meten in plaats van te raden. Databasebeheer is slechts een kwestie van instellen en vergeten als uw gegevens of uw zoekopdrachten nooit veranderen. Anders moet u de prestaties regelmatig controleren om er zeker van te zijn dat er geen problemen optreden.
Met 'klein genoeg' in de bovenstaande opmerkingen bedoel ik dat u zich waarschijnlijk geen zorgen hoeft te maken over de prestatie-impact van zoiets als:
select * from friends where lowercase(lastname) = "smith"
als je maar drie vrienden hebt.
De impact van deze dingen wordt ernstiger naarmate de tafel groter wordt. Als u bijvoorbeeld honderd miljoen klanten heeft en u wilt alle klanten vinden die waarschijnlijk computergerelateerd zijn, dan zou u het volgende niet willen proberen:
select name from customers where lowercase(name) like '%comp%'
Dat zal je DBA's waarschijnlijk naar beneden halen als een hoop stenen.
Een manier waarop we dit in het verleden hebben opgelost, is door redundantie in de gegevens te introduceren. Als we dat eerste voorbeeld gebruiken, zouden we een extra kolom toevoegen met de naam lowerlastname
en vul het in met de kleine letter lastname
. Indexeer dat vervolgens voor zoekdoeleinden en uw select
uitspraken worden verblindend snel, zoals ze zouden moeten zijn.
En wat doet dat met onze geliefde 3NF, hoor ik u vragen? Het antwoord is "niet veel", als je weet wat je doet :-)
U kunt de database zo instellen dat deze nieuwe kolom wordt gevuld met een trigger voor invoegen/bijwerken, om de gegevensconsistentie te behouden. Het is volkomen acceptabel om 3NF om prestatieredenen te breken, op voorwaarde dat je de gevolgen begrijpt en beperkt.
Evenzo kan die tweede query een trigger voor invoegen/bijwerken hebben die een nieuwe geïndexeerde kolom name_contains_comp
bevolkte. telkens wanneer een invoer werd bijgewerkt of ingevoegd die de relevante tekst bevatte.
Aangezien de meeste databases veel vaker worden gelezen dan dat ze worden geschreven, verplaatst dit de kosten van de berekening naar het invoegen/bijwerken, waardoor deze effectief wordt afgeschreven over alle geselecteerde bewerkingen. De vraag zou dan zijn:
select name from customers where name_contains_comp = 'Y'
Nogmaals, je zult de zoekopdracht verblindend snel vinden tegen de kleine kosten van iets langzamere invoegingen en updates.