sql >> Database teknologi >  >> RDS >> Oracle

Oracle:Hvordan man effektivt vælger rækker ved hjælp af en nøgleliste

Det er ikke en god praksis at videregive værdier for IN tilstand som strengsammenkædning. Det første er selvfølgelig sikkerhed og korrekthed, men næste punkt er ydeevne.
Hver gang du kalder sætningsdatabasemotoren analyserer den, opbygger en forespørgselsplan og udfører derefter handlinger specificeret i SQL-sætningen.
Hvis du opbygger forespørgselstekst fra bunden hver gang, og derefter udføres alle tre stadier hver gang.
Men hvis du bruger bindevariabler ser forespørgslen altid ens ud, så databasen bruger en cachelagret forespørgselsplan, hvilket fremskynder udførelse af forespørgsler. Selv du kan kalde oci_parse() kun én gang og genbrug $stmt variabel med forskellige sæt af leverede parametre.
Så for den bedste ydeevne skal du bruge bind-variabelen og udfylde den med array ved hjælp af oci_bind_array_by_name .

Yderligere ting er at hente resultater ved hjælp af oci_fetch_all kan udføre hurtigere end at læse resultatsæt række for række, men det afhænger af logikken i behandlingen af ​​resultaterne.

Opdater

Det ser ud til, at det kun virker at sende array-parametre, hvis du skal udføre PL/SQL-blok og ikke kan bruge det med SQL-sætninger. Men en anden mulighed er at bruge samlinger for at sende en liste over parameterværdier. Det er muligt at opfylde betingelserne for spørgsmålet selv med arrays, men denne måde er mindre elegant.
Udover forskellige måder at forespørge en database på er der sådan noget som systemindstillinger. I tilfælde af PHP er der nogle parametre i php.ini fil, som styrer interaktion med Oracle. En af dem ( oci8.statement_cache_size ) relateret til en forespørgselscaching og ydeevne.

Eksempler

Alle eksempler bruger den samme dataopsætning i Oracle.
For at videregive data vælger jeg foruddefineret SYS.ODCIVarchar2List type, men det er også muligt at definere brugerdefineret type med samme karakteristika (demonstreret i dataopsætningseksempel). Nedenfor er kode til at demonstrere dataskemaopsætning og princippet om brug af samlinger i DML.

SQLFiddle

opret tabel minTabel(værdi varchar2(100), nøgle varchar2(100))/indsæt i minTabel(værdi, nøgle)vælg * fra (vælg 'æble', 'æble_one' fra dual union alt vælg 'æble' ', 'apple_two' fra dual union alle vælg 'banana', 'banana_one' fra dual union alle vælg 'orange', 'orange_one' fra dual union alle vælg 'orange', 'orange_two' fra dual union alle vælg 'kartoffel', 'potato_one' fra dual)/create or replace type TCustomList som tabel for varchar2(4000)/create or replace package TestPackage som type TKeyList er tabel med varchar2(1000) indeks med binært_heltal; function test_select(pKeyList in out TKeyList) return sys_refcursor;end;/create or replace package body TestPackage er funktion test_select(pKeyList in out TKeyList) return sys_refcursor er vParam sys.ODCIVarchar2List :=sys.ODCIVarchar2List(); vCur sys_refcursor; vIdx binært_heltal; start vIdx :=pKeyList.first; while(vIdx er ikke null) loop vParam.Extend; vParam(vParam.last) :=pKeyList(vIdx); vIdx :=pKeyList.next(vIdx); endeløkke; åben vCur for vælg * fra minTabel hvor værdi i (vælg kolonneværdi fra tabel(vParam)); returnere vCur; end;end;/ 

Forespørgsler til demonstration af samlinger:

--vælg efter værdi listselect * fra minTabel hvor værdi i (vælg kolonneværdi fra tabel(Sys.ODCIVarchar2List('banana','kartoffel')))/--samme med brugerdefineret typevælg * fra minTabel hvor værdi i ( vælg kolonneværdi fra tabel(TCustomList('banana','kartoffel')) )/--samme med demonstration af støbning vælg * fra minTabel hvor værdi i (vælg kolonneværdi fra tabel(cast(TCustomList('banana','kartoffel) ') som Sys.ODCIVarchar2List)) )/

Eksempel 1 - opkald fra PHP ved hjælp af samlinger

append($keyList[$i]); } oci_bind_by_name($stmt, 'key_list', $coll, -1, OCI_B_NTY); oci_execute($stmt); while($row =oci_fetch_array($stmt, OCI_ASSOC)) { echo "{$row['KEY']}, {$row['VALUE']}\n"; // Udskriv værdierne } echo "---\n"; $coll->free(); //-- Kør sætning en anden gang med andre parametre //-- uden at gentage. $coll =oci_new_collection($conn, 'ODCIVARCHAR2LIST','SYS'); $coll->append('banan'); oci_bind_by_name($stmt, 'key_list', $coll, -1, OCI_B_NTY); oci_execute($stmt); while($row =oci_fetch_array($stmt, OCI_ASSOC)) { echo "{$row['KEY']}, {$row['VALUE']}\n"; // Udskriv værdierne } echo "---\n"; $coll->free(); oci_free_statement($stmt); oci_close($conn);?> 

Eksempel 2 - Opkald fra PHP ved hjælp af array og pakke

 

Eksempel 3 - opkald fra PHP ved hjælp af array og anonym blok

 


  1. Hvordan skriver jeg en SQL-forespørgsel for et bestemt datointerval og datotidspunkt ved hjælp af SQL Server 2008?

  2. Optimering af GROUP BY + COUNT DISTINCT på ikke-indlejret jsonb-kolonne

  3. Kald til en medlemsfunktion rowCount() på et ikke-objekt

  4. Afkrydsningsfelt med Array inde i looping Falskt resultat?