There are a number of things that can cause the actual plan to differ from the estimated plan (and if you want to get really deep in the weeds, there are lots of things that can cause different methods of producing the actual plan to produce different results but I'll ignore that).
The simplest (and most common) revolve around bind variables. If I do an
EXPLAIN PLAN on a simple query like
WHERE col1 = :1
Oracle has no information about what value I might pass in for
col1 so it does a very generic estimate. If there are 20 distinct values, for example, it will probably guess that the query would need to access 5% of the rows in the table. If you actually execute this statement and pass in a value, on the other hand, Oracle has a lot more information-- it may know from a histogram that the value you passed in will actually require it to access 7% of the rows in the table. If the actual query plan remains unchanged, it's entirely plausible that the
cost would increase by 40% since the expected amount of work grew by 40%.
A complete list of everything that causes details from an estimated query plan to differ from details from an actual query plan and an explanation of how those things interact would be much too long for this format (particularly since a lot of the items get very complicated very quickly). There are situations where statistics on an object are missing, for example, where the optimizer has to do a random sample of the data to infer the statistics at compile time that will differ a bit every time the query is compiled. There are a number of situations where the optimizer has some sort of feedback mechanism that kicks in when a query is being run that it doesn't have when a query plan is being estimated-- it may choose a degree of parallelism based on available resources, it may change the cost of a sort depending on how much PGA space it can get, depending on the version it may be able to change course if an operation retrieves substantially more or less data than it expected. There are effects do to plans being cached or different technologies that try to ensure plan stability kicking in when queries are actually compiled.