Korrelert delspørring

Fra Wikipedia, den frie encyklopedi

En korrelert delspørring i SQL er en delspørring som bruker verdier fra den ytre spørringen. Ettersom delspørringen kan bli evaluert en gang for hver rad som behandles av den ytre spørringen kan en korrelert delspørring være treg.

Likt som for vanlige delspørringer kan korrelerte delspørringer brukes i SELECT-klausulen og WHERE-klausulen (men ikke FROM-klausulen).

Eksempler[rediger | rediger kilde]

Følgende er et eksempel på en typisk korrelert delspørring. I dette eksemplet er målet å liste opp alle ansatte som har lønn over gjennomsnittet for avdelingen deres.

 SELECT employee_number, name
  FROM employees emp
 WHERE salary > (
    SELECT AVG(salary)
     FROM employees
     WHERE department = emp.department);

I spørringen ovenfor er den ytre spørringen

 SELECT employee_number, name
  FROM employees emp
 WHERE salary > ...

, og den indre spørringen (den korrelerte delspørringen) er:

 SELECT AVG(salary)
  FROM employees
 WHERE department = emp.department

I den ovennevnte delspørringen må den indre spørringen utføres på nytt for hver ansatt. (En tilstrekkelig smart implementering kan cache resultatet av den indre spørringen avdeling for avdeling, men selv i beste fall må den indre spørringen utføres en gang per avdeling.)

Korrelerte delspørringer kan brukes andre steder enn bare i WHERE-klausulen. Følgende spørring har for eksempel en korrelert delspørring i SELECT-klausulen for å velge ut listen over alle ansatte sammen med gjennomsnittslønnen for hver ansatte sin avdeling. Også i dette eksempelet, siden delspørringen er korrelert med en kolonne i den ytre spørringen, må den ytre spørringen kjøres på nytt for hver rad i resultatet.

 SELECT employee_number,
    name,
    (SELECT AVG(salary) 
      FROM employees
     WHERE department = emp.department) AS department_average
  FROM employees emp

Korrelerte delspørringer i FROM-klausulen[rediger | rediger kilde]

Vanligvis er det meningsløst å ha en korrelert delspørring i FROM-klausulen ettersom tabellen i FROM-klausulen er nødvendig for å evaluere den ytre spørringen, men den korrelerte delspørringen i FROM-klausulen kan ikke evalueres før den ytre spørringen er evaluert. Dette skaper en sirkulær avhengighet, en høna-og-egget-problemstillng. I dokumentasjonen til MariaDB er dette listet som en begrensning.[1]

I noen databasesystemer er det imidlertid tillatt å bruke korrelerte delspørringer når man skjøter i FROM-klausulen gjennom å bruke et spesifikt nøkkelord for å referere til tabellene listet opp før skjøtingen, hvilket gir flere rader i den korrelerte delspørringen og skjøter dem med tabellen til venstre. I PostgreSQL brukes nøkkelordet LATERAL rett før delspørringen til høyre,[2] mens i Microsoft SQL Server brukes et av nøkkelordene CROSS APPLY eller OUTER APPLY i stedet for JOIN.[3]

Prosessering av korrelerte delspørringer[rediger | rediger kilde]

En mye brukt metode for å prosessere korrelerte delspørringer er å omskrive dem til tilsvarende flate spørringer[4] (en prosess kjent som utflating[5][6][7][8]). Utvikling av algoritmer i den retningen har fordelen med lav kompleksitet. Siden denne tilnærmingen krever tilpasninger kan ikke eksisterende databasesystemer uten videre flate ut korrelerte underspørringer ved å følge noen generelle regler. I tillegg krever denne tilnærmingen stor utviklingsinnsats for å implementere utflatingsalgoritmer i en databasemotor. En generell beregningsmetode er å utføre den nøstede løkken direkte ved å iterere gjennom alle tuplene til de korrelerte kolonnene fra den ytre spørreblokken og utføre delspørringene like mange ganger som antallet tupler i den ytre løkken.[9] Denne enkle tilnærmingen har fordelen at den kan brukes mer generelt siden den ikke påvirkes av hvilke typer korrelerte operatorer som brukes eller strukturen på delspørringene. Ulempen er høy beregningskompleksitet. Akselerering med grafikkprosessor (GPU) er en metode som kan brukes for å signifikant forbedre ytelsen til nøstede metoder med stor algoritmisk kompleksitet ved å utnytte parallellitet og enhetsminnet på GPU-en,[10] og oppnår både målet om programvare designet og implementert for generell bruk og høy ytelse i behandling av delspørringer.

Referanser[rediger | rediger kilde]

  1. ^ «Subquery Limitations». Besøkt 24. desember 2020. 
  2. ^ «Table Expressions - LATERAL Subqueries». Besøkt 21. januar 2023. 
  3. ^ «FROM clause plus JOIN, APPLY, PIVOT (Transact-SQL)». Besøkt 24. desember 2020. 
  4. ^ «On Optimizing an SQL-like Nested Query». 
  5. ^ «The SQLite Query Optimizer Overview - 11. Subquery Flattening». SQLite. Besøkt 21. januar 2023. 
  6. ^ «Flattening FROM Clause Subqueries». Vertica. Besøkt 21. januar 2023. 
  7. ^ «Flattening a subquery into a normal join». Apache Derby. Besøkt 21. januar 2023. 
  8. ^ «Chapter 15: Abstract Query Plan Guide - Flattened subqueries». Sybase. Besøkt 21. januar 2023. 
  9. ^ (pdf). ISBN 089791001X. doi:10.1145/582095.582099. 10.1145/582095.582099 https://dl.acm.org/doi/pdf/10.1145/582095.582099. 
  10. ^ https://ieeexplore.ieee.org/document/9458769/.