top_5_tech_brief.pdf

Upload: ankit-modi

Post on 14-Apr-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/30/2019 top_5_tech_brief.pdf

    1/17

    Five Leading Causes of Oracle DatabasePerformance Problems andHow to Solve Them

    A Buda Consulting Technical Brief

    Robert J. BudaPresidentBuda [email protected]

    February 2011

  • 7/30/2019 top_5_tech_brief.pdf

    2/17

    ii

    Table of Contents

    Introduction ..................................................................................................................................................................1Performance Issue #1: Gathering Statistics............................................................................................................... 1

    Methods of Collecting Statistics .............. ............... ............. ............... .............. .............. .............. .............. ............... . 1

    Gathering Statistics Manually.................................................................................................................................... 1Copying Statistics.......................................................................................................................................................2

    Performance Issue #2: SGA Size................................................................................................................................. 3Controlling the Size of the Overall SGA .................................................................................................................... 4Controlling Individual Sections of the SGA ...............................................................................................................4

    Performance Issue #3: Redo Log Size ........................................................................................................................4Increasing the Size of Log Files .............. ............... ............. ............... .............. .............. .............. .............. ............... . 6

    Performance Issue #4: Index Usage............................................................................................................................ 6What Can Prevent the Use of an Index? ....................................................................................................................8

    Performance Issue #5: Extent Management............................................................................................................ 10Why Reorganize Table Data? .................................................................................................................................. 11Manual Reorganization Methods ............... .............. .............. .............. .............. ............... .............. .............. ........... 12

    Conclusion................................................................................................................................................................... 14About Buda Consulting ............................................................................................................................................. 15

    About the Author ...... ............... .............. .............. .............. .............. ............... .............. .............. .............. .............. .. 15

    Copyright 2011 by Buda Consulting, Inc. All rights reserved. Printed in USA.

    Oracle is a registered trademark of Oracle Corporation. All other marks are property of their respective companies.

    Buda Consulting957 Route 33Hamilton Square, NJ 086901-888-548-1801

  • 7/30/2019 top_5_tech_brief.pdf

    3/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 1

    IntroductionAs we evaluate our clients Oracle database systems and help them solve problems relating toperformance and stability, we see many causes for these issues. However, there are a small number ofbasic issues that tend to cause problems on the majority of systems.

    This paper describes five of the more frequent issues that we see, and discusses how to identify theseproblems and resolve them.

    Performance Issue #1: Gathering StatisticsThe gathering of statistics can have a significant impact on query performance.

    The query optimizers job is to decide the best way to execute a query. It performs these tasks,among others:

    Choose whether to use an index on a query. Choose which index to use if there is more than one index to choose from. Choose which method to use when executing joins.

    The optimizer uses database statistics to make these decisions. To help the optimizer make thesedecisions, Oracle keeps a number of different types of statistics including:

    The cardinality of the tables (number of rows) Information about the distribution of the data in individual columns Storage characteristics of the data

    Frequent and regular statistics gathering will ensure that your optimizer has the best possible datawith which to make its decisions. Otherwise performance can be negatively affected. So be sure tokeep your statistics up-to-date.

    Methods of Collecting StatisticsThere are two methods of collecting statistics: Automatic and Manual.

    Oracle will collect statistics automatically if it is configured to do so. Statistics can be gatheredautomatically by using the job GATHER_STATS_JOB. This job is created automatically when thedatabase is created and is controlled by the scheduler. This job will automatically gather statistics forall objects for which no statistics have been gathered yet, or that have stale statistics associatedwith them; that is, the data has changed by more than 10% since the statistics were gathered.

    Some database administrators choose to collect statistics manually so that they have more controlover when the statistics are collected. If you do not automatically collect statistics, then you mustensure that you collect them whenever the data in the database has changed significantly.

    Gathering Statistics ManuallyThe following command is used to gather statistics on the example schema BIG_DATA. TheGather Auto option illustrated below is the same option that would be used by theGATHER_STATS job for automatic collection. (There are other options that are beyond the scopeof this paper.) Gathering statistics frequently with this method will ensure that your statistics are up-to-date.

  • 7/30/2019 top_5_tech_brief.pdf

    4/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 2

    exec dbms_stats.gather_database_stats(options => 'GATHER AUTO',

    -- include tables with empty or stale statsestimate_percent => dbms_stats.auto_sample_size

    -- auto determine sample size

    )

    Alternatively, you can gather stats for one particular schema with the following command:

    exec dbms_stats.gather_schema_stats(ownname => 'BIG_DATA,

    -- collect stats on the BIG_DATA Schemaoptions => 'GATHER AUTO',

    -- include tables with empty or stale statsestimate_percent => dbms_stats.auto_sample_size

    -- auto determine sample size)

    Other options enable you to collect stats on a specific table or index.

    Copying Statistics

    After statistics have been gathered, they can be copied from one database to another. This is usefulif, for example, you want the optimizer to choose execution paths similar to your production pathson databases that may have a smaller data set, such as development or QA databases.

    This can be done using the following commands:

    -- Create a table to hold the statisticsexec dbms_stats.create_stat_table

    (ownname=>BOB, stattab=>'PRODUCTION_STATISTICS);-- Export statistics to the newly created tableexec dbms_stats.export_schema_stats

    (ownname=>BOB, stattab=> 'PRODUCTION_STATISTICS');-- Export the stats table!exp bob/tiger tables='PRODUCTION_STATISTICS'-- Drop the tabledrop table PRODUCTION_STATISTICS;

    -- Connect to the target databaseconnect bob/tiger-- Import the stats table

    !imp bob/tiger fromuser=bob touser=bob-- Import the statisticsexec dbms_stats.import_schema_stats

    (ownname=>BOB, stattab=>'PRODUCTION_STATISTICS');--Drop the stats tabledrop table 'PRODUCTION_STATISTICS';

  • 7/30/2019 top_5_tech_brief.pdf

    5/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 3

    Performance Issue #2: SGA SizeOracle uses two main memory areas to do its work, the system global area (SGA) and the programglobal area (PGA). This section discusses controlling the size of the SGA. A description of the PGAis also listed for completeness.

    If the SGA is not already configured to take advantage of all available memory on the server, then

    increasing the size can significantly improve performance. Carefully evaluate the available memory,however. Consider total memory on the system and the memory requirements of other applicationson the system.

    As a general rule, I configure Oracle to use about 80% of the remaining memory on Windows afterthe needs of other applications.

    You can see the current size of the SGA by issuing the show sga command at the SQL commandline or by selecting from the v$sga system view. This gives a high-level summary of the SGA size.

    The SGA is a set of buffers that Oracle uses to cache data. It is comprised of the following areas:

    Area InitializationParameter

    Purpose

    Overall SGA sga_target Setting this to a nonzero value turns onthe automatic shared memorymanagement feature and sets the targetvalue.

    Overall SGA sga_max_size Limits the max size of the SGA when youset the individual components manually.

    Default Buffer Cache db_cache_size All cached data that is not directed to oneof the other buffer caches is stored here.

    Recycle_Buffer_Cache db_recycle_cache_size Optional area used for large tables thatshould not be kept in memory becausequeries are unlikely to need the same data

    within a short period of time.

    Keep_Buffer_Cache db_keep_cache_size Optional area used for data that will befrequently used and that you dont wantto be moved out of the cache to makeroom for other data.

    Block Size Caches db_8k_cache_size

    db_16k_cache_size

    Up to five optional caches for specificblock sizes for tablespaces with blocksizesdifferent from the default.

    Shared Pool Shared_Pool_Size Contains optimized query plans, parsedSQL statements, packages, and otheritems that can be shared across sessions.

    Large Pool Large_Pool_Size Optional area used by RMAN.Java Pool Java_Pool_Size Contains all session-specific Java Code.

    Redo_Log_Buffer Log_Buffer_Size Circular buffer that holds informationabout changes made to the database.

    Streams Pool Streams_Pool_Size Streams memory area.

    Table 1: SGA Buffers

  • 7/30/2019 top_5_tech_brief.pdf

    6/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 4

    The PGA is a set of buffers that is allocated for operations performed by user processes. This area iscomprised of:

    Area InitializationParameter

    Purpose

    Sort Area Sort_Area_Size Used for sorting.

    Hash Area Hash_Area_Size Used for merging and other operations.

    Table 2: PGA Buffers

    Controlling the Size of the Overall SGA

    In Oracle 10g and 11i, the SGA size can either be controlled automatically, using automatic segmentspace management (ASSM), as described below, or manually by setting the size of the individualcomponents. Two parameters control the overall size of the SGA.

    SGA_TARGET Setting this to a nonzero value turns on the automatic shared memorymanagement feature and sets the target value for the entire SGA. If this is set, you can stillset sizes of individual components and the system will set the remaining parametersautomatically up to the SGA_MAX_SIZE.

    SGA_MAX_SIZE Limits the max size of the SGA when you set the individualcomponents manually.

    Controlling Individual Sections of the SGA

    In addition to these two parameters, which control the size of the overall SGA, the initializationparameters listed in Table 1 above can be used to control the size of the respective SGA area.

    Tuning the SGA can be a complicated task, and may require looking at all of the SGA areas to

    determine if they are large enough. But as an initial step, if you have large amounts of unusedmemory on your server, consider one of the two options:Increasing the size of either the Default Buffer Cache or the individual Block Size Caches, if you usethem. This will enable Oracle to keep more data in memory and is likely to reduce the number ofphysical reads it needs to perform.

    Turning on ASSM by Setting the SGA_TARGET to the amount of memory that you would likeOracle to use.

    Note: If you choose to use ASSM, I suggest setting the individual SGA component areas to areasonable number. This becomes a minimum setting for these areas. Some customers using ASSMhave reported that when the individual components are not set, performance suffers significantlybecause the automatic resizing can result at times in a very small db_cache_size or other too-smallminimum settings.

    Performance Issue #3: Redo Log SizeIn systems with very high insertion or update rates, online redo log activity is a critical factor toexamine. If the logs are too small, frequent log switches can cause significant delays in processinginserts or updates.

    Redo log files are typically configured in groups of three files. Each time one of the files fills up,Oracle will do a log switch and then begin using the next one in sequence. If archive logging is

  • 7/30/2019 top_5_tech_brief.pdf

    7/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 5

    turned on, the prior redo log is then archived to another location. This process continues until thethird log is filled, and then the first log is reused, as illustrated in Figure 1.

    Figure 1: How Oracles log switching works

    Source: Oracle Database Administrator's Guide, 10g Release 2 (10.2), Part Number B14231-02

    When logs are undersized for the insertion or update rates, logs switch frequently. This results innumerous problems. Here are three of the most typical:

    1. Each of the log switches takes system resources, and so constitutes a general drag on thesystem. Log switches can be seen by viewing the v$loghist system view.

  • 7/30/2019 top_5_tech_brief.pdf

    8/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 6

    2. Very frequent switches can cause a very high number of log sync waits. These waits delay theinsertion of data. Log sync waits can be seen in an automatic workload repository (AWR)report.

    3. If an online log file cannot be archived by the time the system wants to use that file again, noinserts or updates will take place until that file is successfully archived.By increasing the size of the redo log, you can decrease the time between log switches. As a generalrule, you should try to log switch no more frequently than every 20 minutes.

    Increasing the Size of Log Files

    You cannot change the size of existing log files. In order to use larger log files, you must add a newset of larger files and then drop the older files. This can be done as described below.

    You can view information about your logfiles by using the following views:

    V$log Displays redo log information.

    V$logfile Displays information about groups, members, and the corresponding physical files.

    V$loghist Displays information about prior use of the logfiles, including log switches.

    Add new logfiles, and drop old ones, using the following commands:

    Alter database add logfile To add the new, larger logfiles

    Alter system switch logfile To ensure that the old logs are no longer used

    Alter database drop logfile To drop the older logfiles

    After increasing the size of your logs, check v$loghist after a few hours of production usage to see ifthe time between log switches has been increased to more than twenty minutes. If it has not, repeat

    the above process until you have at least twenty minutes between switches.

    Performance Issue #4: Index UsageA very common cause of performance problems is lack of proper indexes or the use of queries thatare not using existing indexes.

    If a query is performing a full table scan on a large table, it is very likely that an index on one or morefields in the table will improve query performance, sometimes significantly.

  • 7/30/2019 top_5_tech_brief.pdf

    9/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 7

    To determine whether a query is using an index, you can view the execution plan of the query. To dothis, use the explain plan command as demonstrated in the following example. For this example,we will use the warehouse_inventory table:

    -- create the table that we will use for our exampleCreate table warehouse_inventory (

    warehouse_id number,

    warehouse_name varchar2(30),product_id number ,qty number);

    -- we will use the following query for our example:

    select * from warehouse_inventory where warehouse_name='AAA';

    -- Issue the explain plan command at the sqlplus prompt:explain plan for select * from warehouse_inventory wherewarehouse_name= 'AAA';

    The above command stores the resulting execution plan in the plan table. Note that this form of theexplain plan command does not give a name to the stored execution plan. Therefore you mustdelete all rows from the plan table before issuing another explain plan command.

    To view the formatted results of the plan, use the following query:

    substr (lpad(' ', level-1) || operation || ' (' || options || ')',1,30) "Operation",object_name "Object"fromplan_tablestart with id = 0connect by prior id=parent_id;

    -- Results look like this:SELECT STATEMENT ()TABLE ACCESS (FULL) WAREHOUSE_INVENTORY

    Note the line that says TABLE ACCESS (FULL), followed by a table name. This indicates that thisquery is not using any indexes for the referenced table.

    After creating an index on the warehouse_name field, the results of the execution plan will reflect theuse of the index.

    -- create an index on the warehouse_name fieldcreate index warehouse_name1_ind onwarehouse_inventory(warehouse_name);

    -- clear the plan tabledelete plan_table;

    -- execute the explain plan againexplain plan for select * from warehouse_inventory wherewarehouse_name='AAA

    -- Query the plan tableselect

  • 7/30/2019 top_5_tech_brief.pdf

    10/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 8

    substr (lpad(' ', level-1) || operation || ' (' || options ||')',1,30 ) "Operation",object_name "Object"fromplan_tablestart with id = 0connect by prior id=parent_id;

    Here are the new results:

    Operation Object------------------------------ ------------------------------SELECT STATEMENT ()TABLE ACCESS (BY INDEX ROWID) WAREHOUSE_INVENTORYINDEX (RANGE SCAN) WAREHOUSE_NAME1_IND

    Note how the newly created index is now used in the execution plan.

    What Can Prevent the Use of an Index?

    There are various causes that could prevent a query from using an index that is available for use. Invalid/stale statistics. As mentioned above, the optimizer uses statistics to determine

    when an index on a given column or group of columns should be used. If statistics are verystale, the optimizer may choose to perform a full table scan even though there is an indexavailable. This can happen, for example, if statistics were gathered when the table had veryfew rows and many rows have been added since the statistics were gathered.

    Use of a function on an indexed column. If a function is applied to a column in theWHERE clause of a query, no index applied directly to that column can be used. This isbecause the original value is indexed, not the result of the function call. For example,recreating the table that we used earlier:

    -- Drop and recreate the tableDrop table warehouse_inventory;Create table warehouse_inventory (

    warehouse_id number,warehouse_name varchar2(30),product_id number ,qty number);

    -- Create an index on the name fieldCreate index wh2_ind onwarehouse_inventory(warehouse_name);

    -- we wish to issue the following querySelect product_id,sum(qty)from warehouse_inventorywhere upper(warehouse_name) = 'NORTH_WAREHOUSE'group by product_id

    -- issue the explain planexplain plan for Select product_id,sum(qty)from warehouse_inventorywhere upper(warehouse_name) = 'NORTH_WAREHOUSE'group by product_id

  • 7/30/2019 top_5_tech_brief.pdf

    11/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 9

    -- Query the plan tableselectsubstr (lpad(' ', level-1) || operation || ' (' || options|| ')',1,30 ) "Operation",object_name "Object"fromplan_tablestart with id = 0connect by prior id=parent_id;

    -- the results of the explain planSELECT STATEMENT ()HASH (GROUP BY)TABLE ACCESS (FULL) WAREHOUSE_INVENTORY

    Even though the warehouse_name column has an index, this index cannot be used becausethe indexed value may not be the same as the result of the upper function.

    However, if you must use a function in the query as above, you can create a functionbased

    index on the function that you are using. For example, to create an index on the function inthe above example:

    -- create the function based indexCREATE INDEX Upper_Warehouse_Name_indON warehouse_inventory (Upper(warehouse_name));

    --clear the plan_tableDelete plan_table;

    -- issue the explain planexplain plan for Select product_id,sum(qty)from warehouse_inventorywhere upper(warehouse_name) = 'NORTH_WAREHOUSE'

    group by product_id-- Query the plan table

    selectsubstr (lpad(' ', level-1) || operation || ' (' || options|| ')',1,30 ) "Operation",object_name "Object"fromplan_tablestart with id = 0connect by prior id=parent_id;

    -- the results of the explain planSELECT STATEMENT ()HASH (GROUP BY)TABLE ACCESS (BY INDEX ROWID WAREHOUSE_INVENTORYINDEX (RANGE SCAN) UPPER_WAREHOUSE_NAME_IND

    The function-based index is now used in the query plan.

  • 7/30/2019 top_5_tech_brief.pdf

    12/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 10

    Use of a non-leading column in an index. Another reason that an index may be ignoredis when the leading column of a multi-column index is not used in the query. Revising theindexes on our warehouse_inventory table gives us:

    Create table warehouse_inventory (warehouse_id number,warehouse_name varchar2(30),

    product_id number ,qty number);

    Create index wh1_ind onwarehouse_inventory(warehouse_id,warehouse_name);

    Select product_id,sum(qty)from warehouse_inventorywhere upper(warehouse_name) = 'NORTH_WAREHOUSE'group by product_id;

    Even though warehouse_name is in the wh1_ind index, it will not be used here because weare not also using the warehouse_id, which is the leading column in the index, in the

    WHERE clause.

    Performance Issue #5: Extent ManagementTo understand this topic, some background on storage structure is helpful.

    Table and index data is stored in segments. Segments are composed of extents, which are in turncomposed of database blocks. Optimally, each row of a table is stored completely in one databaseblock (see Figure 2).

    Each table and each index has one segment, unless it is partitioned, in which case it has one segmentper partition.

  • 7/30/2019 top_5_tech_brief.pdf

    13/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 11

    Figure 2: Storage structure

    Source: Oracle9i Database Concepts, Release 2 (i9.2)d, Part Number A96524-01

    When a table or index is first created, the extents within the segment are on contiguous areas on thedisk. This means there is no empty space between them.

    Why Reorganize Table Data?

    As table data gets updated and deleted, the storage of table data becomes less efficient. The followingconditions reduce the efficiency of the table storage:

    When rows are deleted, empty space remains in the blocks where the rows once were. Thisspace is not available for data unrelated to this table until the table is reorganized. Also, thespace freed within a block due to deletes may not be contiguous.

    Similar to the deletion of a row, when a column value is updated with a smaller value, emptyspace is left in the block.

    If a row is updated and there is not enough free space to fit the entire record in its originaldata block, then Oracle performs row chaining, which can place part of the row in a separateblock.

    If a row is updated and there is not enough room to fit the entire record in the block, butthere is room to fit the record in another block, then Oracle performs row migration. Whenperforming row migration, Oracle places a pointer to the row in the original block andrelocates the entire row to another block.

  • 7/30/2019 top_5_tech_brief.pdf

    14/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 12

    In addition to the impact that these conditions have on query performance, they waste disk space.For these reasons, you need to periodically reorganize database tables in order to ensure that thestorage is efficient.

    Reorganizing will eliminate the empty space, thus freeing up the space for use by other tables. It willalso eliminate chaining and migration of rows.

    Oracle also sometimes coalesces space automatically. As mentioned above, there can be multiplenon-contiguous free areas inside a database block. When this occurs, there are times that Oracle willautomatically coalesce those areas into one large area. According to the Oracle documentation, thiswill occur only when the following occurs:

    An INSERT or UPDATE statement attempts to use a block that contains enough free spaceto contain a new row piece,

    The free space is fragmented so the row piece cannot be inserted in a contiguous section ofthe block.

    Manual Reorganization Methods

    There are multiple methods available to manually reorganize a table. These include:

    Online Segment Shrink Online Table Redefinition CTAS (create table as select * from) Export/Import Flat File/Sql loader

    Online segment shrinkis the best choice when it is available. This option is only available whenlocally managed tablespaces are used with ASSM.

    You can use the Oracle Segment Advisor to identify objects that can benefit from reorganization.This method does not require extra disk space and the object can remain online for queries, inserts,updates, and deletes during most of the operation.

    Using the Segment Advisor is non-trivial. There are multiple ways to do this but unless you haveOracle Enterprise Manager available, the quickest and easiest is to run Segment Advisor manuallyand view the results manually.

    Enterprise Manager is a very useful tool, but many smaller organizations do not have this installedbecause it can be difficult to install and configure. In a future Tech Brief, I will discuss theconfiguration of Enterprise Manager.

    To run the Segment Advisor manually, you must perform the following steps using thedbms_advisor package:

    1. Create an advisor task.2. Create an advisor object (which you will be analyzing).3. Set task parameters.4. Execute the task.

    Detailed instructions for doing this can be found in the section Running the Segment AdvisorManually with PL/SQL in the Oracle documentation.

  • 7/30/2019 top_5_tech_brief.pdf

    15/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 13

    After the Segment Advisor is executed, there are numerous ways to view the results. The simplestway to do this is to use the DBA_ADVISOR views.

    The following examples from the Oracle documentation demonstrate each step of this process.

    First, create, configure, and execute the task. In this example, we are examining the Employees tablein the HR schema.

    After running this procedure, view the status of the task:

    When the task is completed, view the results:

  • 7/30/2019 top_5_tech_brief.pdf

    16/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 14

    After reviewing the results and determining that reorganization is necessary, you can issue the onlineshrink command. The cascade option indicates that index segments associated with the tableshould be shrunk as well.

    Online table redefinition can be used if you need to keep the table online but are not using ASSM.This method requires extra disk space but, like online segment shrink, the table remains available foruse during the operation.

    The online table redefinition process is complex and is beyond the scope of this paper. It is only agood option for this purpose if the table must remain online.

    If the table can be taken offline during the operation, then the following simpler options areavailable.

    1. Using Create table as select * from ..., truncating the table, and then re-inserting from thecopy.

    2. Using export/import to dump the table out to an external file and then bring it back in.3. Unload the data to a flat file and use the SQL Loader utility to bring it back in.

    The best method to choose among these options depends on the size of the table involved and otherfactors. We will explore this further in a future Tech Brief.

    ConclusionThe five topics discussed in this paper are frequently the cause of performance problems in anOracle database. Resolving these issues before they cause problems can help keep your applicationsrunning smoothly and trouble-free.

  • 7/30/2019 top_5_tech_brief.pdf

    17/17

    Five Leading Causes of Oracle Performance Problems and How to Solve Them:A Buda Consulting Technical Brief

    Page 15

    About Buda ConsultingFor over twenty years, Buda Consulting has provided database consulting services to businesses thatneed to harness the potential of their information assets. Specializing in relational database design,application development, database administration and infrastructure support, Buda Consulting solvesits clients business problems quickly through proven expertise in the latest database management

    systems, including Oracle, SQL Server and MySQL.

    Based in Central New Jersey, Buda Consulting serves companies of all sizes throughout the UnitedStates. Our clients include Johnson & Johnson, Wachovia, Johns Hopkins University, City Universityof New York, Aventis Pharmaceutical and Verizon Wireless, as well as city governments, medicaloffices and other small to midsized businesses.

    About the Author

    Robert J. Buda, founder and President of Buda Consulting, has overtwenty years experience in the information technology field. He is anexpert in the design and development of database systems and is certifiedin Oracle Database Administration.