![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
for (int i=0; i<1024*128; i++) { sprintf(sz_key, "aaaa_key_%d", i); key.data = sz_key; key.size = strlen(sz_key) + 1; .... Let's calculate the real data, average key size is 12, so real data is (12+x)*1024*128 Bytes : |
|
data size db files real data db files/real data 16 12M 3.5M 3.43 32 16M 5.5M 2.91 64 24M 9.5M 2.53 128 40M 17.5M 2.29 256 70M 33.5M 2.90 512 120M 65.5M 1.83 1024 522M 129.5M 4.03 2048 522M 257.5M 2.03 4096 1.1G 513.5M 2.14 .... The questiongs are: first, why db files/real data are so large? |
|
second, look at the line when data size is 512 and 1024, the smallest and biggest db files/real data. why? |
#3
| |||
| |||
|
|
likun.navipal (AT) gmail (DOT) com wrote: ... for (int i=0; i<1024*128; i++) { sprintf(sz_key, "aaaa_key_%d", i); key.data = sz_key; key.size = strlen(sz_key) + 1; ... Let's calculate the real data, average key size is 12, so real data is (12+x)*1024*128 Bytes : Actually, the average key size is a bit over 15 bytes; of the 131072 keys, 90,000 are 15 bytes in length. data size db files real data db files/real data 16 12M 3.5M 3.43 32 16M 5.5M 2.91 64 24M 9.5M 2.53 128 40M 17.5M 2.29 256 70M 33.5M 2.90 512 120M 65.5M 1.83 1024 522M 129.5M 4.03 2048 522M 257.5M 2.03 4096 1.1G 513.5M 2.14 ... The questiongs are: first, why db files/real data are so large? The DB format adds overhead in a number of places: - space is needed to track the size of each key and value and the 'type' of each entry, and possibly a byte or two to align the key and/or value (6 to 8 bytes per entry) - B-trees are page based, so there will be some "internal fragmentation" that occurs whenever a new page has to allocated because the previous page didn't have enough free-space for the next key/value pair. This is often expressed as the 'fill-factor', the precentage of total data space that's actually holding information - each page has a header that tracks various things, such as the amount of free space on the page, the page-numbers of the pages before and after it in the tree, and the LSNs for transaction recovery (26 bytes) - the B-tree has internal pages that track the locations of the pages below them - the first page of the B-tree holds metadata for the entire tree (1 page) Also, your code inserts the keys out of sorted order (the key "aaaa_key_13" sorts _before_ "aaaa_key_4") which will result more internal fragmentation (a lower fill-factor) than if you inserted them in sorted order. second, look at the line when data size is 512 and 1024, the smallest and biggest db files/real data. why? If a key or value would take up more than a quarter of the space on a page, then it'll get placed on an 'overflow' page instead and a reference to that page goes on the normal B-tree page. Much of the above is described or discussed in the DB Reference Guide in the DB source tree and at http://www.sleepycat.com/docs/ref/toc.html The db_stat utility can be used to get many statistics about a DB file, such as the fill-factor and the number of overflow pages. Philip Guenther |
#4
| |||
| |||
|
|
likun.navipal (AT) gmail (DOT) com wrote: ... for (int i=0; i<1024*128; i++) { sprintf(sz_key, "aaaa_key_%d", i); key.data = sz_key; key.size = strlen(sz_key) + 1; ... Let's calculate the real data, average key size is 12, so real data is (12+x)*1024*128 Bytes : Actually, the average key size is a bit over 15 bytes; of the 131072 keys, 90,000 are 15 bytes in length. data size db files real data db files/real data 16 12M 3.5M 3.43 32 16M 5.5M 2.91 64 24M 9.5M 2.53 128 40M 17.5M 2.29 256 70M 33.5M 2.90 512 120M 65.5M 1.83 1024 522M 129.5M 4.03 2048 522M 257.5M 2.03 4096 1.1G 513.5M 2.14 ... The questiongs are: first, why db files/real data are so large? The DB format adds overhead in a number of places: - space is needed to track the size of each key and value and the 'type' of each entry, and possibly a byte or two to align the key and/or value (6 to 8 bytes per entry) - B-trees are page based, so there will be some "internal fragmentation" that occurs whenever a new page has to allocated because the previous page didn't have enough free-space for the next key/value pair. This is often expressed as the 'fill-factor', the precentage of total data space that's actually holding information - each page has a header that tracks various things, such as the amount of free space on the page, the page-numbers of the pages before and after it in the tree, and the LSNs for transaction recovery (26 bytes) - the B-tree has internal pages that track the locations of the pages below them - the first page of the B-tree holds metadata for the entire tree (1 page) Also, your code inserts the keys out of sorted order (the key "aaaa_key_13" sorts _before_ "aaaa_key_4") which will result more internal fragmentation (a lower fill-factor) than if you inserted them in sorted order. second, look at the line when data size is 512 and 1024, the smallest and biggest db files/real data. why? If a key or value would take up more than a quarter of the space on a page, then it'll get placed on an 'overflow' page instead and a reference to that page goes on the normal B-tree page. Much of the above is described or discussed in the DB Reference Guide in the DB source tree and at http://www.sleepycat.com/docs/ref/toc.html The db_stat utility can be used to get many statistics about a DB file, such as the fill-factor and the number of overflow pages. Philip Guenther |
#5
| |||
| |||
|
|
1. althouth it has some internal data structures in berkeley db, the db file/real data be high to 4 is hard to understand. |
|
2. you mentioned about "fill-factor", which means the precentage of total data space that's actually holding information. can i control the "fill-factor", e.g., set to 0.8? |
|
3. you said that, If a key or value would take up more than a quarter of the space on a page, then it'll get placed on an 'overflow' page instead. why is a quarter? is it a waste? how can i change it? |
#6
| |||
| |||
|
|
likun.navipal (AT) gmail (DOT) com wrote: 1. althouth it has some internal data structures in berkeley db, the db file/real data be high to 4 is hard to understand. What about it is hard to understand? Did you actually use db_stat and do the math on what it returned to see how much overhead was caused by each factor I mentioned? 2. you mentioned about "fill-factor", which means the precentage of total data space that's actually holding information. can i control the "fill-factor", e.g., set to 0.8? No. In B-trees the fill-factor is a consequence of the sizes of the keys and values and the insertion order and not something you can configure. 3. you said that, If a key or value would take up more than a quarter of the space on a page, then it'll get placed on an 'overflow' page instead. why is a quarter? is it a waste? how can i change it? It's a quarter because the default for the bt_minkeys parameter is 2 and a key/value pair takes 2 slots. For information on how to change that parameter and its effects, please read section 2.5.3 of the reference guide. As for whether that's a waste, that depends on what you're trying to save. Space? Speed of searches? Speed of inserts and deletes? Programming complexity? Since you haven't described the limits that your application needs to run under nor your reasons for using Berkeley DB to begin with, it's impossible to say whether the default key-per-page value or even the factor of four growth is a good tradeoff or a poor one. If the size of the data on disk is the overriding concern than you should consider alternative storage formats. Depending on your tradeoffs, you may be better off completely tossing BDB and hand-coding the storage layer of your application. You're the only one who knows what tradeoffs you're willing to make. Philip Guenther |
#7
| |||
| |||
|
|
I really used db_stat to try to find something, what i want to know is why the db file/real data is from 1.3 to 4. The db_stat for the db which db file/real data is 4 will put at the end. |
#8
| |||
| |||
|
|
likun.navipal (AT) gmail (DOT) com wrote: I really used db_stat to try to find something, what i want to know is why the db file/real data is from 1.3 to 4. The db_stat for the db which db file/real data is 4 will put at the end. Could you run that again, this time with the -d option and the name of the .db file instead of the -e option? The -e option dumps the environment statistics, while the -d options dumps the table statistics for the given table. Philip Guenther |
#9
| |||
| |||
|
|
db_stat -d file-1024.db (data size is 1024), the result is : .... 4096 Underlying database page size 1 Number of levels in the tree 1 Number of unique keys in the tree 1 Number of data items in the tree |
#10
| |||
| |||
|
|
likun.navipal (AT) gmail (DOT) com wrote: db_stat -d file-1024.db (data size is 1024), the result is : ... 4096 Underlying database page size 1 Number of levels in the tree 1 Number of unique keys in the tree 1 Number of data items in the tree Umm, you only have a single item in the table; of course it'll be inefficient space-wise at that point: you don't even have enough data to fill a single page! You should build a database of a size that would/will be 'typical' and snag the stats on it before you start worrying about fill-factors or overhead. Philip Guenther |
![]() |
| Thread Tools | |
| Display Modes | |
| |