sql >> Databasteknik >  >> RDS >> Oracle

Oracle använder eller ignorerar indexerad kolumn beroende på formatet to_date(literal)

Ok - jag ska ge det ett försök, det här är mest avdrag från den tillgängliga informationen:

Varför väljer Oracle en annan genomförandeplan?

Det verkar i din andra fråga med det ovanliga datumformatet att optimeraren inte har någon aning om vad värdet av det resulterande datumet är. Du ser filterpredikatet:

1 - filter(TO_DATE('20140610 ','ååååmmdd ')<=TO_DATE(' 2014-06-10 23:59:59', 'åååå-mm-dd hh24:mi:ss'))

Vilket betyder att optimeraren inte ens är säker på att det första datumet är mindre än det andra! Det betyder att optimeraren inte har någon aning om antalet returnerade rader och kommer bara att använda en generisk plan utan att ta hänsyn till specifik statistik. Det skulle vara samma sak om du hade en användardefinierad funktion xyt() som skulle returnera ett datum för intervallet. Optimeraren har inget sätt att veta vilket datum-värde som kommer att resultera - Detta betyder att du får en allmän plan för alla ändamål, som borde vara ganska anständig för alla angivna datumintervall.

I det första och tredje fallet verkar optimeraren förstå datumet direkt och kan gissa antalet rader som finns i datumintervallet genom att använda statistik. Så medan den andra frågan var till Optimizern som MELLAN X OCH 3 den här frågan är som MELLAN 1 OCH 3 Så han optimerar frågeplanen för det förutsagda antalet returnerade rader!

Det konstiga verkar vara att frågeoptimeraren har sådana problem med ett konstigt datumformat, kan arkiveras som en bugg/begäran om förbättring...

Men en viktig poäng:

  1. En heltabellsgenomsökning behöver inte vara en DÅLIG plan... Förutom att använda ett index är inte alltid snabbare!
  2. Kostnaden i frågeplanen är inte på något sätt direkt relaterad till den faktiska körtiden eller prestandan - det är en intern mätning att jämföra olika planer för SAMMA FRÅGA (Du kan alltså inte jämföra kostnaden för olika frågor som dina frågor 1 ,2 och 3)

Om du returnerar ett stort antal rader från en tabell kommer en hel tabellsökning utan indexåtkomst i många fall att vara mycket snabbare, speciellt när du använder vissa partitioner! - Tabellgenomsökningen kommer bara att få tillgång till behörigheten för det matchande datumintervallet - alltså endast för datumet i fråga och returnerar alla rader från denna partition. Detta är mycket snabbare än att fråga indexet för varje enskild rad och sedan extrahera raden genom indexåtkomst... Försök att profilera frågorna - hela tabellsökningen på partitionen bör vara 3 gånger så snabb med mycket mindre IO



  1. Transaktion MySQL

  2. MYSQL välj frågereturlista över månader som sträng från start-/slutdatum

  3. bevilja till flera db med ett kommando

  4. Konvertera UPDATE till INSERT INTO ON DUPLICATE KEY UPDATE-sats