Forum Discussion
How to Improve Query Reference performance for large tables
- 10 years ago
jaykilleen I see you are aware of things like Table.Buffer, so you are pretty advanced PowerQuery user.
I can go into a little detail about your question. The answer up front is the tip is somewhat true. The rule to remember here is each query, when been loaded to report, will always be evaluated in isolation. They may even be evaluated by different processes and thus not form a dependent tree structure.
For example, if you have a base query A, and then two new queries B and C referencing A. A isn't loaded to report but B and C are. When you hit the Apply button, B and C will simultaneously start loading to report. In both evaluations, A will be evaluated separately, because B isn't aware of C.
Now if we have this model in mind, you can argue the tip isn't true at all. However, PowerQuery evaluations keeps a cache of data seen by evaluations on disk. So if you are within the same cache session and pulled on A multiple times, you will essentially only pay for it the first time (unless of course, you are pulling on different pages of A). This cache will ONLY apply to raw data coming from the data source, any additional transformations will need to be performed on top of it.
Finally, since when you load queries to report, you always want the latest data. So each loading session is essentially a new cache session. Therefore, the tip is somewhat true here. You will only need to pay for the data coming from data source A ONCE per loading all of the queries. (Interestingly for most data sources this is true for duplicates of A as well). However, you will pay for the transformations on top of A N times where N = the number of queries been loaded.
With this knowledge in mind, you can see that Table.Buffer doesn't really help you either. What that does is guarantee a stable output from within a query (e.g., between multiple lets). So essentially you declare a point in your data where from there on all transformations will be done on the local copy, vs folded remotely.
Finally, yes, DirectQuery will most certainly help with the performance here. WIth DQ you always operate on the remote data source and never keep a local copy of the data. So there isn't a "loading" phase. You will pay for the data as the visuals need them (where it's mostly aggregated).
Does this make sense?
Regards,
PQ
ImkeF Your observation is correct. Essentially folding the query differently to the server could potentially break the cache sharing. Whether Table.Buffer make sense in this case is still unclear to me. In the example you gave, if filtering B and C reduces the datasize dramatically, then it may still be better if you push both queries to the server and load the data separately.
We are touching onto implementation details of PowerQuery/PowerBI desktop. It is not a public contract and should only serve as guidelines on how optimization should be carried out. So they aren't documented anywhere, although some experimentation should quickly reveal what's going on behind the scenes.
Hi, thanks for the useful tips.
I wander if we have to index all fields in our source table, on which we are making filters in Power Query?
Is this going to accelerate the selection of the 'right' data for using in PBI?
Thanks
- ImkeF8 years agoCommunity Champion
Not sure what exactly you mean with "Indexing".
If you mean Table.AddIndexColumn, this will slow your queries down.
- Dimitar8 years agoFrequent Visitor
Hi ImkeF,
I mean creating an index in the MySQL database on the fields on which I will filter later in PowerQuery. I expect an index on such fields should help to select the rows which I need to keep in my model.
Thanks
- ImkeF8 years agoCommunity Champion
Yes, that's correct (provided MySQL-queries fold, which I don't know).