You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@iceberg.apache.org by GitBox <gi...@apache.org> on 2022/01/28 16:55:00 UTC

[GitHub] [iceberg] RussellSpitzer commented on issue #3607: Merge Into Performance to Iceberg Table

RussellSpitzer commented on issue #3607:
URL: https://github.com/apache/iceberg/issues/3607#issuecomment-1024416788


   > Hi @RussellSpitzer , sorry to jump on this thread, but I have a question regarding your last message, if you could elaborate, as I think I'm missing a step:
   > 
   > > For example if you say  `purchase_ts = timestampOf(2021-01-01)` and you have actually partitioning on `day(purchase_ts)` it transforms the predicate into `day(purchase_ts) = day(timestampOf(2021-01-01)`.
   > 
   > Surely, `purchase_ts` being a timestamp, has all sorts of values that are not a round day, so to have a predicate transformed into `day(purchase_ts) = day(timestampOf(2021-01-01)`, how would you write it?
   > 
   > * `on target.purchase_ts = timestampOf(2021-01-01)` doesn't seem right, because if `purchase_ts = 2021-01-01 14:10:00.001`, the meaning is actually different
   > * `on target.purchase_ts = timestamp '2021-01-01 14:10:00.001'`, if you know the exact value of the partition key in the target row
   > * `on target.purchase_ts >= timestamp '2021-01-01' and target.purchase_ts < timestamp '2021-01-02'`
   > * I don't think `on day(target.purchase_ts) = '2021-01-01'` or similar works, as far as I've tried?
   > 
   > Thanks!
   
   I think I may have misled you by oversimplifying. The user here still only writes queries using their exact restrictions, Iceberg then uses this restriction to create restrictions which match the partitioning. For example, Iceberg knows a specific timestamp can only occur in a certain day and it can use that information to limit the files read. Iceberg doesn't disregard the original predicate, that stays with the execution engine for actually evaluating rows but Iceberg can still use this timestamp for partition pruning and file evaluation.
   
   For example say you are looking for 
   `ts = 3PM on Aug 12`
   
   First thing we do is look at our manifest_list file, see docs in the [spec](https://iceberg.apache.org/#spec/)
   Each entry there will have a `partitions` field summary column and a `partition_spec_id` to let us know how to use that data. 
   
   We load up the partition spec for the given spec ID and transform the original predicate into one that matches that spec. If our `spec` contains a `day(ts)` transform we take the original predicate and transform it using the `day` transform . So for evaluating this line the original predicate becomes `day(ts) = projectDay(3pm Aug 12) = Aug 12`. 
   
   With this new transform we evaluate all the `partitions` listed in this file. These values only contain `day(ts)` since that is the only thing kept by the spec. If any pass we know the particular manifest file may have valid datafiles to be scanned.
   
   Once we have a list of all the possible manifest files that may have hits we play this game again. Now we check against `ManifestEntries`. Every entry contains a `partition` value and then details about the `datafile` (spec_id is inherited from the entry in manifest_list). 
   
   Here we can do two steps of evaluation for each individual data file. First we can use the transformed predicate (`day(ts) = Aug 12`) to check if the partition value is a match, if so we then move to evaluating the individual metrics of the file. Here we would use the original predicate and would check whether the `3PM on Aug 12` is a possible value for the timestamp column of each file based on the min and max values for that column. If datafile passes both of these checks we keep it for the scan.
   
   The scan then contains of all data files which we know **may** have our given row, this is transformed into a set of tasks for whatever execution engine is in use and evaluated. The execution engine then will use its own logic to filter individual rows with the original predicates (YMMV based on engine specific implementations).
   
   So what happens if we cannot transform a predicate into the partition spec? Or what if a data file was inserted into the table when it was unpartitioned? In both of these cases we default to "this file may contain the row we are looking for" and return it to the engine. For example, suppose you have a predicate `age > 10` and a partition spec of `bucket(age,128)`. There is no way to project a [greater than predicate](https://github.com/apache/iceberg/blob/f960698a04266270a8eaf9e23e8b55e97e550564/api/src/main/java/org/apache/iceberg/transforms/Bucket.java#L131-L134) into a valid bucket predicate so we simply have to say all partitions may match. 
   
   ### 
   My big TLDR here is:
   
   As a user you query on normal columns, Iceberg attempts to transform your predicates into ones that match the partitioning of the files within the table to prune out files. When Iceberg cannot transform the predicates it simply assumes there may be a match and returns those files to the execution engine which does the actual row level filtering.
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org