Friday, June 7, 2024
SQL/PGQ and graph theory
Friday, May 3, 2024
Property graphs: elements, labels and properties
A property graph consists of three types of "things" in it: elements, labels and properties.
Elements are nodes or edges in the graphs. They form the basic structure of a graph. An edge connects two nodes. Two nodes may be connected by multiple edges corresponding to different relationships between them.
Labels classify the elements. An element may belong to multiple classes and thus have multiple labels.
Properties are key-value pairs providing more information about an element. All the elements with the same label expose same set of keys or properties. A property of a given element may be exposed through multiple labels associated with that element.
Wednesday, April 24, 2024
PostgreSQL's memory allocations
There's a thread on hackers about recovering memory consumed by paths. A reference count is maintained in each path. Once paths are created for all the upper level relations that a given relation participates in, any unused paths, for which reference count is 0, are freed. This adds extra code and CPU cycles to traverse the paths, maintain reference counts and free the paths. Yet, the patch did not show any performance degradation. I was curious to know why. I ran a small experiment.
Experiment
I wrote an extension palloc_test which adds two SQL-callable functions palloc_pfree() and mem_context_free() written in C. Function definitions can be found here. The first function palloc's some memory and then pfree's it immediately. Other function just palloc's but never pfrees, assuming that the memory will be freed when the per-tuple memory context is freed. Both functions take the number of iterations and size of memory allocated in each iteration respectively as inputs. These functions return amount of time taken to execute the loop allocating memory. It appears that the first function spends CPU cycles to free memory and the second one doesn't. So the first one should be slower than the second one.
Results
The table below shows the amount of time reported by the respective functions to execute the loop as many times as the value in the first column, each iteration allocating 100 bytes. The figure shows the same as a plot. The time taken to finish the loop increases linearly for both the function indicating that the palloc logic is O(n) in terms of number of allocations. But the lines cross each other around 300K allocations.
count | palloc_pfree | memory context reset |
100 | 0.0029 | 0.007124 |
100100 | 2.5646 | 5.079862 |
200100 | 5.1682 | 10.375552 |
300100 | 7.6373 | 15.704286 |
400100 | 10.1827 | 19.038238 |
500100 | 12.7013 | 23.847599 |
600100 | 15.2838 | 28.708501 |
700100 | 17.8255 | 36.982928 |
800100 | 20.3718 | 41.863638 |
900100 | 23.0706 | 44.332727 |
1000100 | 51.3311 | 52.546201 |
2000100 | 56.7407 | 104.747792 |
3000100 | 76.3961 | 154.225157 |
4000100 | 102.3415 | 206.510045 |
5000100 | 126.1954 | 256.367685 |
6000100 | 155.8812 | 314.178951 |
7000100 | 179.9267 | 367.597501 |
8000100 | 206.2112 | 420.003351 |
9000100 | 234.7584 | 474.137076 |
Inference and conclusion
This agrees with the observations I posted on the thread. Instead of letting all the useless path to be freed when query finishes, freeing them periodically during planning is time efficient as well as memory efficient. It compensates for the extra CPU cycles spent to maintain reference counts, traverse and free paths.
The actual memory allocation and freeing pattern as implemented in that patch is different from that in the experiment, so it might be worth repeating those experiments by simulating similar pattern.
I used chunk size of 100 since I thought it's closer to the order of average path size. But it might be worth repeating the experiment with larger chunk sizes to generalize the result.
Tuesday, April 23, 2024
DBaaG with SQL/PGQ
For those who have studied ERD-lore, it's not new that a relational database is very much like a graph. But it has taken SQL, more than 30 years since it became a standard and almost half a century since its inception to incorporate construct that will allow a DataBase to be treated as a Graph, DBaaG. This is surprising given that SQL was developed as language for relational databases which are modeled using ER diagrams. Better late than never. SQL/PGQ has arrived as 16th part of SQL:2023.
Entity Relationship Diagram, ERD in short, is a tool to model and visualize a database as entity types (which classify the things of interest) and relationships that can exist between them. Entity types and the relationships both map to relations in a Relational DataBase Management System (RDBMS in short). The rows in the relations represent entities (instances of entity types) and relationship between entities respectively. Fig. 1 below shows an ERD for a hypothetical shop.
This diagram very much looks like a graph with entity types represented as nodes and relationships represented by edges. That's exactly what SQL/PGQ is about. It adds language constructs to SQL to present underlying database as a "Property Graph". For example, property graph definition corresponding to the above ERD would look like