sql >> Databasteknik >  >> RDS >> Oracle

Vilka är prestandakonsekvenserna av Oracle IN-klausul utan anslutningar?

Om statistiken på din tabell är korrekt borde det vara mycket osannolikt att optimeraren skulle välja att göra en tabellsökning istället för att använda primärnyckelindexet när du bara har 1000 hårdkodade element i WHERE klausul. Det bästa tillvägagångssättet skulle vara att samla in (eller ställa in) korrekt statistik på dina objekt eftersom det borde få bra saker att hända automatiskt istället för att försöka träna mycket gymnastik för att komma runt felaktig statistik.

Om vi ​​antar att statistiken är felaktig i den grad att optimeraren skulle kunna tro att en tabellsökning skulle vara effektivare än att använda primärnyckelindexet, kan du eventuellt lägga till en DYNAMIC_SAMPLING ledtråd som skulle tvinga optimeraren att samla in mer exakt statistik innan den optimerar uttalandet eller en CARDINALITY tips för att åsidosätta optimerarens standarduppskattning av kardinalitet. Ingen av dessa skulle kräva att veta något om de tillgängliga indexen, det skulle bara kräva att man känner till tabellaliaset (eller namnet om det inte finns något alias). DYNAMIC_SAMPLING skulle vara det säkrare, mer robusta tillvägagångssättet, men det skulle lägga till tid till analyssteget.

Om du bygger upp en SQL-sats med ett variabelt antal hårdkodade parametrar i en IN klausul kommer du sannolikt att skapa prestandaproblem för dig själv genom att översvämma din delade pool med icke-delbar SQL och tvinga databasen att spendera mycket tid på att analysera varje variant separat. Det skulle vara mycket effektivare om du skapade en enda delbar SQL-sats som kunde tolkas en gång. Beroende på var din IN klausulvärden kommer från, som kan se ut ungefär som

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

eller

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

eller

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

Om du fick dig ner till en enda delbar SQL-sats, skulle du, förutom att undvika kostnaden för att ständigt analysera påståendet, ha ett antal alternativ för att tvinga fram en viss plan som inte innebär att ändra SQL-satsen. Olika versioner av Oracle har olika alternativ för planstabilitet - det finns lagrade konturer , SQL-planhantering , och SQL-profiler bland andra tekniker beroende på din version. Du kan använda dessa för att tvinga fram särskilda planer för särskilda SQL-satser. Om du fortsätter att generera nya SQL-satser som måste analyseras om, blir det dock mycket svårt att använda dessa tekniker.




  1. 3 sätt att kontrollera en kolumns datatyp i PostgreSQL

  2. Hur man exporterar SQL Server-data från tabell till en CSV-fil

  3. SQL - Ge mig bara 3 träffar för varje typ

  4. En översikt över cachelagring för PostgreSQL