Practical Use of the RDB$DB_KEY.By Bjørge Sæther, Delphi / Interbase programmer.
About the sample code: The examples below are the results of months of efforts trying to perform a large financial analysis on a large database (> 4Gb) within reasonable timings. The real breakthrough came with the introduction of the RDB$DB_KEY. In addition to enormous speed increase, it minimized the need for indexing, thus making both development and implementation both safer and easier. It should be emphasized, though, that you should make comparisons from time to time. After "having seen the light", you may easily overlook simpler (and faster) possible statements. The samples could of course be rewritten in a more tutorial fashion. This takes quite some time, and I also wanted to show a few real-world examples (as opposed to the "CUSTOMER - like" examples). And remember: These procedures are being run on tables having up to 6 million rows. The "success stories" of some of them is like reducing execution time from 1 hr 30 min down to 7 min when introducing the db_key. Another tip when working with large databases: Field/Record size. Although VARCHAR fields don't occupy more space in the database than the actual string lengths require, there is one often overlooked consequence of having some "head room" in VARCHAR field sizes: When selecting rows from a table, equally sized record buffers are allocated, so the size is determined from max possible VARCHAR lengths. This is true when selecting from a client, but also when the server is storing a copy of the record (multi-generation handling) while updating & deleting ! So, watch out ! The following update statement will result in the server allocating 100Mb of RAM per some 80-90,000 records: Table:CREATE TABLE TEST (ID INTEGER, STATUS INTEGER, SOMESTRING VARCHAR 1024); UPDATE
...so, trim your fields !
General: The RDB$DB_KEY may be used is an unique key representing no cost in maintenance or in use. In stored procedures and as a parameter in an update- or delete-sql it is the most efficient record identification you may find in IB. · the db_key is not troubled with index balancing, · the db_key is available also when having no unique index. Very useful when it is desirable to drop a unique key while performing updates or deletes. · The db_key does not depend on available server RAM to be efficient, so it's more and more useful as the ration [size of dataset] / [database RAM size] grows. It's possible to perform fast updates/deletes with very little RAM allocated on the server using the db_key. · the db_key is slightly faster than locating rows through an unique index. · No PLANS necessary whatsoever.
Some tips: · Use DB_KEY with a FOR SELECT loop when a large part of the records are to be updated, and you would normally use a where-clause. In such cases, indices are not very efficient.
Example: Different possible sources for getting a certain value, no joins. Approx. 3/4 of the records will be updated.
· Avoid creating an index needed only for conditional updates/deletes, replace with FOR SELECT loop and DB_KEY Indexing has a cost: It's slowing down delete & update. And, if you do a lot of changes in indexed columns, indices are getting unbalanced, with a penalty in performance. When you need to do a conditional update / delete on a table it may be a solution to use the db_key, where no indices are needed. The larger the ratio updates / rowcount, the larger is the gain of using db_key. · Setting a value in table based on values in joined tables - use an optimized FOR SELECT loop with DB_KEY and values from joined tables selected into variables One way to do fast updates when you want to set a value in a table based on field values of a related table, is to create one FOR SELECT statement with related tables joined, and perform updates based on the db_key value of the driving table.
Example: Updating value in smaller table with value retrieved from master table.
Example: Joining master table with 2 smaller tables.
Example: Joining master table with smaller table joined twice.
Example: Master table joined with two smaller tables.
|
This page was last updated on 2000-05-26 04:28:45 |