sql >> Database >  >> RDS >> Oracle

Wat zijn de gevolgen voor de prestaties van de Oracle IN-clausule zonder joins?

Als de statistieken in uw tabel nauwkeurig zijn, zou het zeer onwaarschijnlijk moeten zijn dat de optimizer ervoor zou kiezen om een ​​tabelscan uit te voeren in plaats van de primaire sleutelindex te gebruiken wanneer u slechts 1000 hardgecodeerde elementen in de WHERE hebt. clausule. De beste aanpak zou zijn om nauwkeurige statistieken over uw objecten te verzamelen (of in te stellen), aangezien dat ervoor zou moeten zorgen dat goede dingen automatisch gebeuren in plaats van te proberen veel gymnastiek te doen om onjuiste statistieken te omzeilen.

Als we aannemen dat de statistieken zo onnauwkeurig zijn dat de optimizer zou denken dat een tabelscan efficiënter zou zijn dan het gebruik van de primaire sleutelindex, zou u mogelijk een DYNAMIC_SAMPLING kunnen toevoegen hint die de optimizer zou dwingen om nauwkeurigere statistieken te verzamelen voordat de instructie of een CARDINALITY wordt geoptimaliseerd hint om de standaard kardinaliteitsschatting van de optimizer te negeren. Voor geen van beide hoeft u iets te weten over de beschikbare indexen, u hoeft alleen de tabelalias te kennen (of de naam als er geen alias is). DYNAMIC_SAMPLING zou de veiligere, robuustere benadering zijn, maar het zou tijd toevoegen aan de parseerstap.

Als u een SQL-statement opbouwt met een variabel aantal hardgecodeerde parameters in een IN clausule, zult u waarschijnlijk prestatieproblemen voor uzelf creëren door uw gedeelde pool te overspoelen met niet-deelbare SQL en de database te dwingen veel tijd te besteden aan het hard ontleden van elke variant afzonderlijk. Het zou veel efficiënter zijn als u een enkele deelbare SQL-instructie zou maken die één keer zou kunnen worden geparseerd. Afhankelijk van waar uw IN clausulewaarden vandaan komen, dat kan er ongeveer zo uitzien

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM global_temporary_table);

of

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM TABLE( nested_table ));

of

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM some_other_source);

Als je jezelf tot een enkele deelbare SQL-instructie hebt gebracht, dan zou je, naast het vermijden van de kosten van het voortdurend opnieuw ontleden van de instructie, een aantal opties hebben om een ​​bepaald plan af te dwingen waarbij de SQL-instructie niet hoeft te worden gewijzigd. Verschillende versies van Oracle hebben verschillende opties voor planstabiliteit -- er zijn opgeslagen overzichten , SQL-planbeheer , en SQL-profielen onder andere technologieën, afhankelijk van uw release. U kunt deze gebruiken om bepaalde plannen voor bepaalde SQL-instructies te forceren. Als u echter steeds nieuwe SQL-instructies genereert die opnieuw moeten worden geparseerd, wordt het erg moeilijk om deze technologieën te gebruiken.




  1. Een tabelruimte maken in postgresql

  2. MySQL C API-compilatiefout, crtdbg.h niet gevonden

  3. CodeIgniter PDO-databasestuurprogramma werkt niet

  4. Dump Oracle-tabel(len)gegevens naar INSERT-instructies