Question

I am trying to upgrade many views performance for some work of mine, and i am doing things now like removing subquerys, calls to other functions in select (functions that make selects inside it), and making things by Join. I would like to know if its the right choice, even thinking that i get better results for retrieving the view with no filters (lets say 20000 rows), it is not so clear that it will grant me a better result for, lets say, 200 rows. How do you face this views where you have many results, or joinning then is kind of expensive?

What else could i consider to improve performance?

I've been looking in some questions here and ppl are talking about orthogonal and i dont get it. In this link there is a answer from user jjanes, where he talks about orthogonal, but it is not that clear. Somebody know and can explain to me how the "orthogonal" concept can be thought with Joins and Subquerys? View doesn't increase performance of correlated subquery?

(This is just concept subject, but i use postgre)

Thanks

Was it helpful?

Solution

Ok, so here is a basic guide to optimizing views (and other long queries) in PostgreSQL.

The first thing is to understand that the more information the planner has, the better. Calls to functions are sometimes unavoidable but you have to understand that they are usually planner-opaque, which means, effectively, that the planner cannot fold in the logic into the main query, and has to run the query separately. So removing functions is a good first step (unless your view merely wraps a function, in which case there is no benefit to doing this).

The second thing to understand is that views encapsulate data logic, and while this may seem like a good thing, it has many, many pitfalls. SQL programming is just about the opposite of good object-oriented design in this regard, in part because SQL is declarative and in part because it is rigorously organized (making debugging of a much longer statement easier than a comparably long function in, say, Python). So one thing to do is to remove joins against views in other views.

Imagine, for example, if I have a view with, say, joins (which is not excessive, really). But then I run a query on the view with a self-join. Now I have gone from 9 joins to 81 and the problem is not evident from looking at the query that caused the problem (but boy, look at the query plan!).

In general your best views are going to be one of three kinds:

  1. Simple function wrappers. For example:

    CREATE VIEW current_stock_list AS select * from parts_stock_list(now());
    
  2. Simple subsets of other tables or views (but not of views wrapping functions), for example:

    CREATE VIEW warehouse_current_stock AS select * onhand_stock WHERE warehouse = 1;
    
  3. Large, complex queries hitting underlying tables. 100 line queries would be preferable to 10 line queries if you avoid joining against views and functions in the process.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top